Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Shen, Siran
wacc
Commits
707be08f
Commit
707be08f
authored
Mar 19, 2021
by
Tom Zhao
Browse files
xz1919: removed all debugging print message
parent
20abce83
Changes
6
Expand all
Hide whitespace changes
Inline
Side-by-side
src/backend/InstructionGenerator.java
View file @
707be08f
package
backend
;
import
backend.arm.ARMInstructionGenerator
;
import
backend.arm.instructions.ARMInstruction
;
import
backend.common.LabelInstruction
;
import
backend.intel.IntelInstructionGenerator
;
import
backend.intel.instructions.IntelInstruction
;
import
java.util.ArrayList
;
import
java.util.List
;
import
utils.NodeVisitor
;
import
utils.frontend.symbolTable.SymbolTable
;
public
abstract
class
InstructionGenerator
<
T
extends
Instruction
>
implements
NodeVisitor
<
Void
>
{
/* the code section of the assembly code */
protected
final
List
<
T
>
instructions
;
/* record the current symbolTable used during instruction generation */
...
...
src/backend/InstructionPrinter.java
View file @
707be08f
package
backend
;
public
abstract
class
InstructionPrinter
{
public
abstract
String
translate
();
public
abstract
String
translate
();
}
src/backend/arm/ARMInstructionGenerator.java
View file @
707be08f
package
backend.arm
;
import
static
backend
.
arm
.
instructions
.
LDR
.
LdrMode
.*;
import
static
backend
.
arm
.
instructions
.
STR
.
StrMode
.*;
import
static
backend
.
arm
.
instructions
.
addressing
.
AddressingMode2
.
AddrMode2
.*;
import
static
backend
.
arm
.
instructions
.
arithmeticLogic
.
ARMArithmeticLogic
.
armUnopAsm
;
import
static
backend
.
arm
.
instructions
.
ARMInstructionRoutines
.
routineFunctionMap
;
import
static
backend
.
arm
.
instructions
.
LDR
.
LdrMode
.
LDR
;
import
static
backend
.
arm
.
instructions
.
LDR
.
LdrMode
.
LDRSB
;
import
static
backend
.
arm
.
instructions
.
STR
.
StrMode
.
STR
;
import
static
backend
.
arm
.
instructions
.
STR
.
StrMode
.
STRB
;
import
static
backend
.
arm
.
instructions
.
addressing
.
ARMImmediate
.
BitNum
.
CONST8
;
import
static
backend
.
arm
.
instructions
.
addressing
.
Operand2
.
Operand2Operator
.*;
import
static
backend
.
arm
.
instructions
.
addressing
.
AddressingMode2
.
AddrMode2
.
OFFSET
;
import
static
backend
.
arm
.
instructions
.
addressing
.
AddressingMode2
.
AddrMode2
.
PREINDEX
;
import
static
backend
.
arm
.
instructions
.
addressing
.
Operand2
.
Operand2Operator
.
ASR
;
import
static
backend
.
arm
.
instructions
.
addressing
.
Operand2
.
Operand2Operator
.
LSL
;
import
static
backend
.
arm
.
instructions
.
arithmeticLogic
.
ARMArithmeticLogic
.
armUnopAsm
;
import
static
frontend
.
node
.
expr
.
UnopNode
.
Unop
.
MINUS
;
import
static
utils
.
Utils
.
ARM_POINTER_SIZE
;
import
static
utils
.
Utils
.
BOOL_BASIC_TYPE
;
import
static
utils
.
Utils
.
BRANCH_HEADER
;
import
static
utils
.
Utils
.
CHAR_ARRAY_TYPE
;
import
static
utils
.
Utils
.
CHAR_BASIC_TYPE
;
import
static
utils
.
Utils
.
FALSE
;
import
static
utils
.
Utils
.
FUNC_HEADER
;
import
static
utils
.
Utils
.
INT_BASIC_TYPE
;
import
static
utils
.
Utils
.
MAIN_BODY_NAME
;
import
static
utils
.
Utils
.
MSG_HEADER
;
import
static
utils
.
Utils
.
PAIR_TYPE
;
import
static
utils
.
Utils
.
RoutineInstruction
;
import
static
utils
.
Utils
.
RoutineInstruction
.*;
import
static
utils
.
Utils
.
SystemCallInstruction
.*;
import
static
utils
.
Utils
.*;
import
static
backend
.
arm
.
instructions
.
ARMInstructionRoutines
.
routineFunctionMap
;
import
static
utils
.
backend
.
Cond
.*;
import
static
utils
.
backend
.
register
.
arm
.
ARMConcreteRegister
.*;
import
static
utils
.
Utils
.
RoutineInstruction
.
CHECK_ARRAY_BOUND
;
import
static
utils
.
Utils
.
RoutineInstruction
.
CHECK_DIVIDE_BY_ZERO
;
import
static
utils
.
Utils
.
RoutineInstruction
.
CHECK_NULL_POINTER
;
import
static
utils
.
Utils
.
RoutineInstruction
.
FREE_ARRAY
;
import
static
utils
.
Utils
.
RoutineInstruction
.
FREE_PAIR
;
import
static
utils
.
Utils
.
RoutineInstruction
.
PRINT_BOOL
;
import
static
utils
.
Utils
.
RoutineInstruction
.
PRINT_CHAR
;
import
static
utils
.
Utils
.
RoutineInstruction
.
PRINT_INT
;
import
static
utils
.
Utils
.
RoutineInstruction
.
PRINT_LN
;
import
static
utils
.
Utils
.
RoutineInstruction
.
PRINT_REFERENCE
;
import
static
utils
.
Utils
.
RoutineInstruction
.
PRINT_STRING
;
import
static
utils
.
Utils
.
RoutineInstruction
.
READ_CHAR
;
import
static
utils
.
Utils
.
RoutineInstruction
.
READ_INT
;
import
static
utils
.
Utils
.
RoutineInstruction
.
THROW_OVERFLOW_ERROR
;
import
static
utils
.
Utils
.
RoutineInstruction
.
THROW_RUNTIME_ERROR
;
import
static
utils
.
Utils
.
STRING_BASIC_TYPE
;
import
static
utils
.
Utils
.
SystemCallInstruction
.
EXIT
;
import
static
utils
.
Utils
.
SystemCallInstruction
.
MALLOC
;
import
static
utils
.
Utils
.
TRUE
;
import
static
utils
.
Utils
.
WORD_SIZE
;
import
static
utils
.
backend
.
Cond
.
EQ
;
import
static
utils
.
backend
.
Cond
.
NE
;
import
static
utils
.
backend
.
Cond
.
NULL
;
import
static
utils
.
backend
.
Cond
.
VS
;
import
static
utils
.
backend
.
register
.
arm
.
ARMConcreteRegister
.
LR
;
import
static
utils
.
backend
.
register
.
arm
.
ARMConcreteRegister
.
PC
;
import
static
utils
.
backend
.
register
.
arm
.
ARMConcreteRegister
.
SP
;
import
static
utils
.
backend
.
register
.
arm
.
ARMConcreteRegister
.
r0
;
import
static
utils
.
backend
.
register
.
arm
.
ARMConcreteRegister
.
r1
;
import
static
utils
.
backend
.
register
.
arm
.
ARMConcreteRegister
.
r4
;
import
backend.Instruction
;
import
backend.InstructionGenerator
;
import
backend.arm.instructions.*
;
import
backend.arm.instructions.ARMInstruction
;
import
backend.arm.instructions.B
;
import
backend.arm.instructions.BL
;
import
backend.arm.instructions.Cmp
;
import
backend.arm.instructions.LDR
;
import
backend.arm.instructions.LDR.LdrMode
;
import
backend.arm.instructions.
STR.StrMode
;
import
backend.arm.instructions.
addressing.*
;
import
backend.arm.instructions.
arithmeticLogic.*
;
import
backend.arm.instructions.
LTORG
;
import
backend.arm.instructions.
Label
;
import
backend.arm.instructions.
Mov
;
import
backend.arm.instructions.Pop
;
import
backend.arm.instructions.Push
;
import
backend.arm.instructions.STR
;
import
backend.arm.instructions.STR.StrMode
;
import
backend.arm.instructions.addressing.ARMImmediate
;
import
backend.arm.instructions.addressing.AddressingMode2
;
import
backend.arm.instructions.addressing.ImmedAddress
;
import
backend.arm.instructions.addressing.Operand2
;
import
backend.arm.instructions.arithmeticLogic.ARMArithmeticLogic
;
import
backend.arm.instructions.arithmeticLogic.Add
;
import
backend.arm.instructions.arithmeticLogic.Sub
;
import
backend.common.address.Address
;
import
frontend.node.*
;
import
frontend.node.expr.*
;
import
frontend.node.FuncNode
;
import
frontend.node.ProgramNode
;
import
frontend.node.StructDeclareNode
;
import
frontend.node.expr.ArrayElemNode
;
import
frontend.node.expr.ArrayNode
;
import
frontend.node.expr.BinopNode
;
import
frontend.node.expr.BinopNode.Binop
;
import
frontend.node.expr.BoolNode
;
import
frontend.node.expr.CharNode
;
import
frontend.node.expr.ExprNode
;
import
frontend.node.expr.FunctionCallNode
;
import
frontend.node.expr.IdentNode
;
import
frontend.node.expr.IntegerNode
;
import
frontend.node.expr.PairElemNode
;
import
frontend.node.expr.PairNode
;
import
frontend.node.expr.StringNode
;
import
frontend.node.expr.StructElemNode
;
import
frontend.node.expr.StructNode
;
import
frontend.node.expr.UnopNode
;
import
frontend.node.expr.UnopNode.Unop
;
import
frontend.node.stat.*
;
import
frontend.node.stat.AssignNode
;
import
frontend.node.stat.DeclareNode
;
import
frontend.node.stat.ExitNode
;
import
frontend.node.stat.ForNode
;
import
frontend.node.stat.FreeNode
;
import
frontend.node.stat.IfNode
;
import
frontend.node.stat.JumpNode
;
import
frontend.node.stat.JumpNode.JumpType
;
import
frontend.node.stat.PrintNode
;
import
frontend.node.stat.PrintlnNode
;
import
frontend.node.stat.ReadNode
;
import
frontend.node.stat.ReturnNode
;
import
frontend.node.stat.ScopeNode
;
import
frontend.node.stat.SkipNode
;
import
frontend.node.stat.StatNode
;
import
frontend.node.stat.SwitchNode
;
import
frontend.node.stat.SwitchNode.CaseStat
;
import
frontend.node.stat.WhileNode
;
import
frontend.type.Type
;
import
java.util.ArrayList
;
import
java.util.Collections
;
...
...
@@ -42,9 +126,9 @@ import java.util.Map;
import
java.util.Set
;
import
java.util.stream.Collectors
;
import
utils.backend.LabelGenerator
;
import
utils.backend.register.Register
;
import
utils.backend.register.arm.ARMConcreteRegister
;
import
utils.backend.register.arm.ARMConcreteRegisterAllocator
;
import
utils.backend.register.Register
;
public
class
ARMInstructionGenerator
extends
InstructionGenerator
<
ARMInstruction
>
{
...
...
@@ -52,29 +136,26 @@ public class ARMInstructionGenerator extends InstructionGenerator<ARMInstruction
public
static
int
MAX_STACK_STEP
=
(
1
<<
10
);
/* const used in visitBinop, for checking multiply overflow */
public
static
int
ASR_SHIFT_CONST
=
31
;
/* the ARM concrete register allocator */
private
final
ARMConcreteRegisterAllocator
armRegAllocator
;
/* the .data section of the assembly code */
protected
final
Map
<
Label
,
String
>
dataSegmentMessages
;
/* call getLabel() on branchLabelGenerator to get label in the format of "L0, L1, L2, ..." */
protected
final
LabelGenerator
<
Label
>
branchLabelGenerator
;
/* call getLabel() on msgLabelGenerator to get label in the format of "msg_0, msg_1, msg_2, ..."*/
protected
final
LabelGenerator
<
Label
>
msgLabelGenerator
;
/* the ARM concrete register allocator */
private
final
ARMConcreteRegisterAllocator
armRegAllocator
;
/* a list of instructions for storing different helper functions
* would be appended to the end of instructions list while printing */
private
final
List
<
ARMInstruction
>
ARMRoutines
;
/* record which helpers already exist, we don't want repeated helper functions */
private
final
Set
<
RoutineInstruction
>
alreadyExist
;
/* call getLabel() on branchLabelGenerator to get label in the format of "L0, L1, L2, ..." */
protected
final
LabelGenerator
<
Label
>
branchLabelGenerator
;
/* call getLabel() on msgLabelGenerator to get label in the format of "msg_0, msg_1, msg_2, ..."*/
protected
final
LabelGenerator
<
Label
>
msgLabelGenerator
;
/* used for mapping type with its print routine function */
private
final
Map
<
Type
,
RoutineInstruction
>
typeRoutineMap
=
Map
.
of
(
INT_BASIC_TYPE
,
PRINT_INT
,
CHAR_BASIC_TYPE
,
PRINT_CHAR
,
BOOL_BASIC_TYPE
,
PRINT_BOOL
,
STRING_BASIC_TYPE
,
PRINT_STRING
,
CHAR_ARRAY_TYPE
,
PRINT_STRING
INT_BASIC_TYPE
,
PRINT_INT
,
CHAR_BASIC_TYPE
,
PRINT_CHAR
,
BOOL_BASIC_TYPE
,
PRINT_BOOL
,
STRING_BASIC_TYPE
,
PRINT_STRING
,
CHAR_ARRAY_TYPE
,
PRINT_STRING
);
public
ARMInstructionGenerator
()
{
...
...
@@ -134,7 +215,8 @@ public class ARMInstructionGenerator extends InstructionGenerator<ARMInstruction
/* visit the content */
for
(
int
i
=
0
;
i
<
node
.
getElemCount
();
i
++)
{
visit
(
node
.
getElem
(
i
));
instructions
.
add
(
new
STR
(
armRegAllocator
.
curr
(),
new
AddressingMode2
(
OFFSET
,
addrReg
,
node
.
getElemOffset
(
i
)),
STR
));
instructions
.
add
(
new
STR
(
armRegAllocator
.
curr
(),
new
AddressingMode2
(
OFFSET
,
addrReg
,
node
.
getElemOffset
(
i
)),
STR
));
armRegAllocator
.
free
();
}
...
...
@@ -335,7 +417,8 @@ public class ARMInstructionGenerator extends InstructionGenerator<ARMInstruction
/* 2 call function with B instruction */
String
overloadName
=
node
.
getFunction
().
getOverloadName
();
String
actualFuncName
=
(
overloadName
!=
null
)
?
overloadName
:
node
.
getFunction
().
getFunctionName
();
String
actualFuncName
=
(
overloadName
!=
null
)
?
overloadName
:
node
.
getFunction
().
getFunctionName
();
instructions
.
add
(
new
BL
(
FUNC_HEADER
+
actualFuncName
));
/* 3 add back stack pointer */
...
...
@@ -709,8 +792,10 @@ public class ARMInstructionGenerator extends InstructionGenerator<ARMInstruction
Label
nextLabel
=
branchLabelGenerator
.
getLabel
().
asArmLabel
();
/* restore the last jump-to label after visiting the while-loop body */
Label
lastBreakJumpToLabel
=
currBreakJumpToLabel
==
null
?
null
:
currBreakJumpToLabel
.
asArmLabel
();
Label
lastContinueJumpToLabel
=
currContinueJumpToLabel
==
null
?
null
:
currContinueJumpToLabel
.
asArmLabel
();
Label
lastBreakJumpToLabel
=
currBreakJumpToLabel
==
null
?
null
:
currBreakJumpToLabel
.
asArmLabel
();
Label
lastContinueJumpToLabel
=
currContinueJumpToLabel
==
null
?
null
:
currContinueJumpToLabel
.
asArmLabel
();
currBreakJumpToLabel
=
nextLabel
;
currContinueJumpToLabel
=
testLabel
;
...
...
@@ -724,7 +809,7 @@ public class ARMInstructionGenerator extends InstructionGenerator<ARMInstruction
/* 3 loop body */
visit
(
node
.
getBody
());
/* restore parent loop stack size */
breakSectionStackSize
=
prevBreakLoopSize
;
continueSectionStackSize
=
prevContinueLoopSize
;
...
...
@@ -859,8 +944,10 @@ public class ARMInstructionGenerator extends InstructionGenerator<ARMInstruction
Label
incrementLabel
=
branchLabelGenerator
.
getLabel
().
asArmLabel
();
/* restore the last jump-to label after visiting the for-loop body */
Label
lastBreakJumpToLabel
=
currBreakJumpToLabel
==
null
?
null
:
currBreakJumpToLabel
.
asArmLabel
();
Label
lastContinueJumpToLabel
=
currContinueJumpToLabel
==
null
?
null
:
currContinueJumpToLabel
.
asArmLabel
();
Label
lastBreakJumpToLabel
=
currBreakJumpToLabel
==
null
?
null
:
currBreakJumpToLabel
.
asArmLabel
();
Label
lastContinueJumpToLabel
=
currContinueJumpToLabel
==
null
?
null
:
currContinueJumpToLabel
.
asArmLabel
();
currBreakJumpToLabel
=
nextLabel
;
currContinueJumpToLabel
=
incrementLabel
;
...
...
@@ -879,7 +966,7 @@ public class ARMInstructionGenerator extends InstructionGenerator<ARMInstruction
/* restore parent loop stack size */
breakSectionStackSize
=
prevBreakLoopSize
;
continueSectionStackSize
=
prevContinueLoopSize
;
/* here we also need to append the for-loop increment at the end */
instructions
.
add
(
incrementLabel
);
visit
(
node
.
getIncrement
());
...
...
@@ -898,7 +985,7 @@ public class ARMInstructionGenerator extends InstructionGenerator<ARMInstruction
armRegAllocator
.
free
();
/* 4 conditional branch jump to the start of loop */
instructions
.
add
(
new
B
(
EQ
,
bodyLabel
.
getName
()));
/* 5 add the label for the following instructions after for-loop */
instructions
.
add
(
nextLabel
);
...
...
@@ -928,7 +1015,7 @@ public class ARMInstructionGenerator extends InstructionGenerator<ARMInstruction
visit
(
node
.
getExpr
());
List
<
Label
>
cLabels
=
new
ArrayList
<>();
for
(
CaseStat
c
:
node
.
getCases
())
{
visit
(
c
.
getExpr
());
Label
cLabel
=
branchLabelGenerator
.
getLabel
().
asArmLabel
();
...
...
@@ -942,7 +1029,8 @@ public class ARMInstructionGenerator extends InstructionGenerator<ARMInstruction
Label
afterLabel
=
branchLabelGenerator
.
getLabel
().
asArmLabel
();
/* restore the jump-to label after visiting the switch cases and default */
Label
lastBreakJumpToLabel
=
currBreakJumpToLabel
==
null
?
null
:
currBreakJumpToLabel
.
asArmLabel
();
Label
lastBreakJumpToLabel
=
currBreakJumpToLabel
==
null
?
null
:
currBreakJumpToLabel
.
asArmLabel
();
currBreakJumpToLabel
=
afterLabel
;
instructions
.
add
(
new
B
(
NULL
,
defaultLabel
.
getName
()));
...
...
@@ -962,7 +1050,7 @@ public class ARMInstructionGenerator extends InstructionGenerator<ARMInstruction
instructions
.
add
(
defaultLabel
);
visit
(
node
.
getDefault
());
breakSectionStackSize
=
prevLoopSize
;
currBreakJumpToLabel
=
lastBreakJumpToLabel
;
...
...
@@ -975,7 +1063,7 @@ public class ARMInstructionGenerator extends InstructionGenerator<ARMInstruction
while
(
stackSize
>
0
)
{
int
realStackSize
=
stackSize
/
MAX_STACK_STEP
>=
1
?
MAX_STACK_STEP
:
stackSize
;
instructions
.
add
(
new
Add
(
SP
,
SP
,
new
Operand2
(
realStackSize
)));
new
Operand2
(
realStackSize
)));
stackSize
=
stackSize
-
realStackSize
;
}
}
...
...
@@ -984,7 +1072,7 @@ public class ARMInstructionGenerator extends InstructionGenerator<ARMInstruction
while
(
stackSize
>
0
)
{
int
realStackSize
=
stackSize
/
MAX_STACK_STEP
>=
1
?
MAX_STACK_STEP
:
stackSize
;
instructions
.
add
(
new
Sub
(
SP
,
SP
,
new
Operand2
(
realStackSize
)));
new
Operand2
(
realStackSize
)));
stackSize
=
stackSize
-
realStackSize
;
}
}
...
...
src/backend/intel/IntelInstructionGenerator.java
View file @
707be08f
This diff is collapsed.
Click to expand it.
src/frontend/SemanticChecker.java
View file @
707be08f
package
frontend
;
import
static
utils
.
Utils
.
ARRAY_TYPE
;
import
static
utils
.
Utils
.
AssemblyArchitecture
;
import
static
utils
.
Utils
.
BOOL_BASIC_TYPE
;
import
static
utils
.
Utils
.
CHAR_BASIC_TYPE
;
import
static
utils
.
Utils
.
CmpEnumMapping
;
import
static
utils
.
Utils
.
EqEnumMapping
;
import
static
utils
.
Utils
.
INT_BASIC_TYPE
;
import
static
utils
.
Utils
.
PAIR_TYPE
;
import
static
utils
.
Utils
.
QUAD_SIZE
;
import
static
utils
.
Utils
.
SEMANTIC_ERROR_CODE
;
import
static
utils
.
Utils
.
STRING_BASIC_TYPE
;
import
static
utils
.
Utils
.
STRING_BASIC_TYPE_INTEL
;
import
static
utils
.
Utils
.
STRUCT_TYPE
;
import
static
utils
.
Utils
.
WORD_SIZE
;
import
static
utils
.
Utils
.
binopEnumMapping
;
import
static
utils
.
Utils
.
bitwiseOpEnumMapping
;
import
static
utils
.
Utils
.
cmpStatAllowedTypes
;
import
static
utils
.
Utils
.
escCharMap
;
import
static
utils
.
Utils
.
findOverloadFuncName
;
import
static
utils
.
Utils
.
formatFuncName
;
import
static
utils
.
Utils
.
freeStatAllowedTypes
;
import
static
utils
.
Utils
.
intParse
;
import
static
utils
.
Utils
.
isCharInRange
;
import
static
utils
.
Utils
.
isInteger
;
import
static
utils
.
Utils
.
lookUpWithNotFoundException
;
import
static
utils
.
Utils
.
overloadSeparator
;
import
static
utils
.
Utils
.
readStatAllowedTypes
;
import
static
utils
.
Utils
.
typeCheck
;
import
static
utils
.
Utils
.
unopEnumMapping
;
import
static
utils
.
Utils
.
unopTypeMapping
;
import
static
utils
.
frontend
.
SemanticErrorHandler
.
branchStatementMutipleError
;
import
static
utils
.
frontend
.
SemanticErrorHandler
.
branchStatementPositionError
;
import
static
utils
.
frontend
.
SemanticErrorHandler
.
charOperatorRangeError
;
import
static
utils
.
frontend
.
SemanticErrorHandler
.
functionJunkAfterReturn
;
import
static
utils
.
frontend
.
SemanticErrorHandler
.
importFileErrorException
;
import
static
utils
.
frontend
.
SemanticErrorHandler
.
invalidFuncArgCount
;
import
static
utils
.
frontend
.
SemanticErrorHandler
.
invalidFunctionReturnExit
;
import
static
utils
.
frontend
.
SemanticErrorHandler
.
invalidPairError
;
import
static
utils
.
frontend
.
SemanticErrorHandler
.
invalidRuleException
;
import
static
utils
.
frontend
.
SemanticErrorHandler
.
overloadUnclearTypeError
;
import
static
utils
.
frontend
.
SemanticErrorHandler
.
returnFromMainError
;
import
static
utils
.
frontend
.
SemanticErrorHandler
.
symbolNotFound
;
import
static
utils
.
frontend
.
SemanticErrorHandler
.
symbolRedeclared
;
import
frontend.antlr.WACCLexer
;
import
frontend.antlr.WACCParser
;
import
frontend.antlr.WACCParser.*
;
import
frontend.antlr.WACCParser.AndExprContext
;
import
frontend.antlr.WACCParser.ArithmeticExprContext
;
import
frontend.antlr.WACCParser.ArrayExprContext
;
import
frontend.antlr.WACCParser.ArrayTypeContext
;
import
frontend.antlr.WACCParser.Array_elemContext
;
import
frontend.antlr.WACCParser.Array_literContext
;
import
frontend.antlr.WACCParser.Array_typeContext
;
import
frontend.antlr.WACCParser.AssignStatContext
;
import
frontend.antlr.WACCParser.BinaryExprContext
;
import
frontend.antlr.WACCParser.BitwiseExprContext
;
import
frontend.antlr.WACCParser.BoolExprContext
;
import
frontend.antlr.WACCParser.BoolTypeContext
;
import
frontend.antlr.WACCParser.BreakStatContext
;
import
frontend.antlr.WACCParser.CharExprContext
;
import
frontend.antlr.WACCParser.CharTypeContext
;
import
frontend.antlr.WACCParser.CmpExprContext
;
import
frontend.antlr.WACCParser.ContinueStatContext
;
import
frontend.antlr.WACCParser.DeclarationContext
;
import
frontend.antlr.WACCParser.DeclareStatContext
;
import
frontend.antlr.WACCParser.DoWhileStatContext
;
import
frontend.antlr.WACCParser.EmptyStructExprContext
;
import
frontend.antlr.WACCParser.EqExprContext
;
import
frontend.antlr.WACCParser.ExitStatContext
;
import
frontend.antlr.WACCParser.ExprContext
;
import
frontend.antlr.WACCParser.ForStatContext
;
import
frontend.antlr.WACCParser.ForStatSeqContext
;
import
frontend.antlr.WACCParser.FreeStatContext
;
import
frontend.antlr.WACCParser.FstExprContext
;
import
frontend.antlr.WACCParser.FuncContext
;
import
frontend.antlr.WACCParser.FunctionCallContext
;
import
frontend.antlr.WACCParser.HexExprContext
;
import
frontend.antlr.WACCParser.IdExprContext
;
import
frontend.antlr.WACCParser.IdentContext
;
import
frontend.antlr.WACCParser.IfStatContext
;
import
frontend.antlr.WACCParser.Import_fileContext
;
import
frontend.antlr.WACCParser.IntExprContext
;
import
frontend.antlr.WACCParser.IntTypeContext
;
import
frontend.antlr.WACCParser.LibraryContext
;
import
frontend.antlr.WACCParser.NewPairContext
;
import
frontend.antlr.WACCParser.OctalExprContext
;
import
frontend.antlr.WACCParser.OrExprContext
;
import
frontend.antlr.WACCParser.PairElemPairTypeContext
;
import
frontend.antlr.WACCParser.PairExprContext
;
import
frontend.antlr.WACCParser.PairTypeContext
;
import
frontend.antlr.WACCParser.Pair_typeContext
;
import
frontend.antlr.WACCParser.ParamContext
;
import
frontend.antlr.WACCParser.ParenExprContext
;
import
frontend.antlr.WACCParser.PrintStatContext
;
import
frontend.antlr.WACCParser.PrintlnStatContext
;
import
frontend.antlr.WACCParser.ProgramContext
;
import
frontend.antlr.WACCParser.ReadStatContext
;
import
frontend.antlr.WACCParser.ReturnStatContext
;
import
frontend.antlr.WACCParser.ScopeStatContext
;
import
frontend.antlr.WACCParser.SeqStatContext
;
import
frontend.antlr.WACCParser.SkipStatContext
;
import
frontend.antlr.WACCParser.SndExprContext
;
import
frontend.antlr.WACCParser.StrExprContext
;
import
frontend.antlr.WACCParser.StringTypeContext
;
import
frontend.antlr.WACCParser.StructContext
;
import
frontend.antlr.WACCParser.StructElemExprContext
;
import
frontend.antlr.WACCParser.StructExprContext
;
import
frontend.antlr.WACCParser.StructTypeContext
;
import
frontend.antlr.WACCParser.Struct_elemContext
;
import
frontend.antlr.WACCParser.Struct_typeContext
;
import
frontend.antlr.WACCParser.SwitchStatContext
;
import
frontend.antlr.WACCParser.UnopExprContext
;
import
frontend.antlr.WACCParser.WhileStatContext
;
import
frontend.antlr.WACCParserBaseVisitor
;
import
frontend.node.StructDeclareNode
;
import
java.io.File
;
import
java.io.FileInputStream
;
import
java.io.FileNotFoundException
;
import
java.io.IOException
;
import
java.util.*
;
import
frontend.node.FuncNode
;
import
frontend.node.Node
;
import
frontend.node.ProgramNode
;
import
frontend.node.StructDeclareNode
;
import
frontend.node.TypeDeclareNode
;
import
frontend.node.expr.*
;
import
frontend.node.stat.*
;
import
frontend.node.expr.ArrayElemNode
;
import
frontend.node.expr.ArrayNode
;
import
frontend.node.expr.BinopNode
;
import
frontend.node.expr.BinopNode.Binop
;
import
frontend.node.expr.BoolNode
;
import
frontend.node.expr.CharNode
;
import
frontend.node.expr.ExprNode
;
import
frontend.node.expr.FunctionCallNode
;
import
frontend.node.expr.IdentNode
;
import
frontend.node.expr.IntegerNode
;
import
frontend.node.expr.PairElemNode
;
import
frontend.node.expr.PairNode
;
import
frontend.node.expr.StringNode
;
import
frontend.node.expr.StructElemNode
;
import
frontend.node.expr.StructNode
;
import
frontend.node.expr.UnopNode
;
import
frontend.node.expr.UnopNode.Unop
;
import
frontend.node.stat.AssignNode
;
import
frontend.node.stat.DeclareNode
;
import
frontend.node.stat.ExitNode
;
import
frontend.node.stat.ForNode
;
import
frontend.node.stat.FreeNode
;
import
frontend.node.stat.IfNode
;
import
frontend.node.stat.JumpNode
;
import
frontend.node.stat.JumpNode.JumpContext
;
import
frontend.node.stat.JumpNode.JumpType
;
import
frontend.node.stat.PrintNode
;
import
frontend.node.stat.PrintlnNode
;
import
frontend.node.stat.ReadNode
;
import
frontend.node.stat.ReturnNode
;
import
frontend.node.stat.ScopeNode
;
import
frontend.node.stat.SkipNode
;
import
frontend.node.stat.StatNode
;
import
frontend.node.stat.SwitchNode
;
import
frontend.node.stat.SwitchNode.CaseStat
;
import
frontend.node.expr.BinopNode.Binop
;
import
frontend.node.expr.UnopNode.Unop
;
import
frontend.type.*
;
import
org.antlr.v4.runtime.tree.TerminalNode
;
import
frontend.node.stat.WhileNode
;
import
frontend.type.ArrayType
;
import
frontend.type.PairType
;
import
frontend.type.StructType
;
import
frontend.type.Type
;
import
java.io.File
;
import
java.io.FileInputStream
;
import
java.io.FileNotFoundException
;
import
java.io.IOException
;
import
java.util.ArrayList
;
import
java.util.HashMap
;
import
java.util.HashSet
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Set
;
import
java.util.Stack
;
import
org.antlr.v4.runtime.CharStream
;
import
org.antlr.v4.runtime.CharStreams
;
import
org.antlr.v4.runtime.CommonTokenStream
;
import
org.antlr.v4.runtime.ParserRuleContext
;
import
org.antlr.v4.runtime.tree.TerminalNode
;
import
utils.frontend.ParserErrorHandler
;
import
utils.frontend.symbolTable.Symbol
;
import
utils.frontend.symbolTable.SymbolTable
;
import
static
utils
.
frontend
.
SemanticErrorHandler
.*;
import
static
utils
.
Utils
.*;
public
class
SemanticChecker
extends
WACCParserBaseVisitor
<
Node
>
{
/* record all files that have been imported */
private
static
final
Set
<
String
>
allImportCollection
=
new
HashSet
<>();
/* global data struct table, used to record all struct */
private
final
Map
<
String
,
StructDeclareNode
>
globalStructTable
;
/* global function table, used to record all functions */
private
final
Map
<
String
,
FuncNode
>
globalFuncTable
;
/**
* SemanticChecker will not only check the semantics of the provided .wacc file, but also generate
* an internal representation of the program using ExprNode and StatNode. This will aid the
...
...
@@ -50,46 +195,27 @@ public class SemanticChecker extends WACCParserBaseVisitor<Node> {
/* where the compiling file lives, used for determine include file */
private
String
path
;
/* recording the current SymbolTable during parser tree visits */
private
SymbolTable
currSymbolTable
;
/* global data struct table, used to record all struct */
private
final
Map
<
String
,
StructDeclareNode
>
globalStructTable
;
/* global function table, used to record all functions */
private
final
Map
<
String
,
FuncNode
>
globalFuncTable
;
/* used after function declare step, to detect RETURN statement in main body */
private
boolean
isMainFunction
;
/* used in determining whether branching statement is legal, i.e. break/continue is within a loop/switch */
private
Stack
<
Boolean
>
isBreakAllowed
;
private
Stack
<
Boolean
>
isContinueAllowed
;
private
Stack
<
Boolean
>
isJumpRepeated
;
private
Stack
<
JumpContext
>
jumpContext
;
/* record the for-loop incrementer so that break and continue know what to do before jumping */
private
Stack
<
StatNode
>
currForLoopIncrementBreak
;
private
Stack
<
StatNode
>
currForLoopIncrementContinue
;
private
final
Stack
<
Boolean
>
isBreakAllowed
;
private
final
Stack
<
Boolean
>
isContinueAllowed
;
private
final
Stack
<
Boolean
>
isJumpRepeated
;
private
final
Stack
<
JumpContext
>
jumpContext
;
/* used only in function declare step, to check function has the correct return type */
private
Type
expectedFunctionReturn
;
/* record whether a skipable semantic error is found in visiting to support checking of multiple errors */
private
boolean
semanticError
;
/* record which file have already been included, IN the current import chain */
private
Set
<
String
>
libraryCollection
;
/* record all files that have been imported */
private
static
Set
<
String
>
allImportCollection
=
new
HashSet
<>();
private
final
Set
<
String
>
libraryCollection
;
/* for function overload */
private
Set
<
String
>
overloadFuncNames
=
new
HashSet
<>();
private
final
Set
<
String
>
overloadFuncNames
=
new
HashSet
<>();
/* indicate the architecture */
private
AssemblyArchitecture
arch
;
private
final
AssemblyArchitecture
arch
;
/* constructor of SemanticChecker */