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
01e6cfff
Commit
01e6cfff
authored
Mar 19, 2021
by
Tom Zhao
Browse files
Merge branch 'develop' of
https://gitlab.doc.ic.ac.uk/lab2021_spring/wacc_46
into develop
parents
ddafa6ad
f68b39d5
Changes
91
Expand all
Hide whitespace changes
Inline
Side-by-side
antlr_config/WACCParser.g4
View file @
01e6cfff
...
@@ -77,7 +77,7 @@ assign_rhs : expr #Expr
...
@@ -77,7 +77,7 @@ assign_rhs : expr #Expr
arg_list : expr (COMMA expr)*;
arg_list : expr (COMMA expr)*;
struct_elem : IDENT (DOT IDENT)+;
struct_elem : IDENT (DOT IDENT)+;
new_struct : NEW IDENT OPEN_
CURLY_BRACKET
arg_list? CLOSE_
CURLY_BRACKET
;
new_struct : NEW IDENT OPEN_
PARENTHESES
arg_list? CLOSE_
PARENTHESES
;
pair_elem : FST expr #FstExpr
pair_elem : FST expr #FstExpr
| SND expr #SndExpr
| SND expr #SndExpr
...
...
scripts/constantPropagationTest.sh
View file @
01e6cfff
...
@@ -25,11 +25,9 @@ for folder in ${VALID_EXAMPLES[@]}; do
...
@@ -25,11 +25,9 @@ for folder in ${VALID_EXAMPLES[@]}; do
echo
$file
echo
$file
./compile
-t
-o1
$file
>
"
${
EXECUTABLE_FILE_NAME
}
.log.txt"
./compile
-t
-o1
$file
>
"
${
EXECUTABLE_FILE_NAME
}
.log.txt"
mv
"
${
EXECUTABLE_FILE_NAME
}
.log.txt"
"
${
VALID_EXAMPLES_SRC_DIR
}${
folder
}
/
${
FILE_NAME
}
.log"
if
diff
"
${
EXECUTABLE_FILE_NAME
}
.log.txt"
"
${
VALID_EXAMPLES_SRC_DIR
}${
folder
}
/
${
FILE_NAME
}
.log"
-I
scope
;
then
((
COUNTER +
=
1
))
# if diff "${EXECUTABLE_FILE_NAME}.log.txt" "${VALID_EXAMPLES_SRC_DIR}${folder}/${FILE_NAME}.log" -I scope; then
fi
# (( COUNTER += 1 ))
# fi
echo
"
$COUNTER
/
$((
$TOTAL_COUNT
))
files have been executed"
echo
"
$COUNTER
/
$((
$TOTAL_COUNT
))
files have been executed"
...
...
scripts/extensionValidTest.sh
View file @
01e6cfff
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
VALID_EXAMPLES
=(
VALID_EXAMPLES
=(
"/binOctHex"
"/binOctHex"
"/bitwise
Operation
"
"/bitwise"
"/do-while"
"/do-while"
"/for"
"/for"
"/import"
"/import"
...
...
scripts/intelAssembleExecute.sh
View file @
01e6cfff
...
@@ -2,13 +2,13 @@
...
@@ -2,13 +2,13 @@
VALID_EXAMPLES
=(
VALID_EXAMPLES
=(
#"/advanced"
#"/advanced"
#
"/array"
"/array"
"/basic"
"/basic"
"/expressions"
"/expressions"
#
"/function"
"/function"
"/if"
"/if"
"/IO"
"/IO"
#
"/pairs"
"/pairs"
#"/runtimeErr"
#"/runtimeErr"
"/scope"
"/scope"
"/sequence"
"/sequence"
...
@@ -44,7 +44,7 @@ for folder in ${VALID_EXAMPLES[@]}; do
...
@@ -44,7 +44,7 @@ for folder in ${VALID_EXAMPLES[@]}; do
./compile
-i
$file
2>
"
${
EXECUTABLE_FILE_NAME
}
.log.txt"
./compile
-i
$file
2>
"
${
EXECUTABLE_FILE_NAME
}
.log.txt"
mv
"
${
FILE_NAME
}
.s"
"
${
EXECUTABLE_FILE_NAME
}
.s"
mv
"
${
FILE_NAME
}
.s"
"
${
EXECUTABLE_FILE_NAME
}
.s"
gcc
"
${
EXECUTABLE_FILE_NAME
}
.s"
-o
"
${
EXECUTABLE_FILE_NAME
}
"
gcc
"
${
EXECUTABLE_FILE_NAME
}
.s"
-o
"
${
EXECUTABLE_FILE_NAME
}
"
./
"
${
EXECUTABLE_FILE_NAME
}
"
>
"
${
EXECUTABLE_OUTPUT_FILE
}
"
timeout
3
./
"
${
EXECUTABLE_FILE_NAME
}
"
>
"
${
EXECUTABLE_OUTPUT_FILE
}
"
# Generate the result from reference compiler
# Generate the result from reference compiler
cat
<
(
echo
"N"
|
$REF_COMPILE
$file
-x
)
|
awk
'/===========================================================/ {x=!x; if(x) next} x==1 {print}'
>
temp
cat
<
(
echo
"N"
|
$REF_COMPILE
$file
-x
)
|
awk
'/===========================================================/ {x=!x; if(x) next} x==1 {print}'
>
temp
# Use the result generated by our compiler
# Use the result generated by our compiler
...
...
src/Compiler.java
View file @
01e6cfff
...
@@ -52,7 +52,6 @@ public class Compiler {
...
@@ -52,7 +52,6 @@ public class Compiler {
File
sourceFile
=
new
File
(
args
[
0
]);
File
sourceFile
=
new
File
(
args
[
0
]);
File
file
=
new
PreCompiler
(
sourceFile
).
preCompile
();
File
file
=
new
PreCompiler
(
sourceFile
).
preCompile
();
// System.out.println(file.getName());
// try-with-resources so that fis can be closed properly even when error occurs
// try-with-resources so that fis can be closed properly even when error occurs
try
(
FileInputStream
fis
=
new
FileInputStream
(
file
))
{
try
(
FileInputStream
fis
=
new
FileInputStream
(
file
))
{
// Input stream of the file
// Input stream of the file
...
...
src/PreCompiler.java
View file @
01e6cfff
...
@@ -73,8 +73,8 @@ public class PreCompiler {
...
@@ -73,8 +73,8 @@ public class PreCompiler {
str
=
str
.
split
(
commentMark
,
2
)[
0
];
str
=
str
.
split
(
commentMark
,
2
)[
0
];
if
(
str
.
contains
(
defineRuleContext
))
{
if
(
str
.
contains
(
defineRuleContext
))
{
/* process and store the macros info */
/* process and store the macros info */
String
[]
macro
=
str
.
split
(
" "
,
3
);
String
[]
macro
=
str
.
trim
().
split
(
" "
,
3
);
if
(
macro
.
length
!=
3
||
macro
[
0
].
length
()
!=
defineRuleContext
.
length
()
-
1
)
{
if
(
macro
.
length
!=
3
||
!
macro
[
0
].
equals
(
defineRuleContext
.
trim
())
)
{
mediateFile
.
delete
();
mediateFile
.
delete
();
System
.
out
.
println
(
"Invalid macro at line "
+
lineCounter
);
System
.
out
.
println
(
"Invalid macro at line "
+
lineCounter
);
System
.
exit
(
SYNTAX_ERROR_CODE
);
System
.
exit
(
SYNTAX_ERROR_CODE
);
...
@@ -82,12 +82,12 @@ public class PreCompiler {
...
@@ -82,12 +82,12 @@ public class PreCompiler {
macros
.
add
(
new
MacroInfo
(
macro
[
1
],
macro
[
2
]));
macros
.
add
(
new
MacroInfo
(
macro
[
1
],
macro
[
2
]));
}
else
if
(
str
.
contains
(
includeRuleContext
))
{
}
else
if
(
str
.
contains
(
includeRuleContext
))
{
/* process and store the stdlib including info */
/* process and store the stdlib including info */
String
[]
tokens
=
str
.
split
(
"<"
,
2
);
String
[]
tokens
=
str
.
trim
().
split
(
"<"
,
2
);
/* e.g. include lib<a, b, c>, tokens[0] = include lib, tokens[1] = a, b, c> */
/* e.g. include lib<a, b, c>, tokens[0] = include lib, tokens[1] = a, b, c> */
String
[]
prefix
=
tokens
[
0
].
split
(
" "
,
2
);
String
[]
prefix
=
tokens
[
0
].
split
(
" "
,
2
);
String
libName
=
prefix
[
1
];
String
libName
=
prefix
[
1
]
.
trim
()
;
List
<
String
>
typeParams
=
(
tokens
.
length
==
1
)
?
new
ArrayList
<>()
:
getTypeParam
(
tokens
[
1
],
List
<
String
>
typeParams
=
(
tokens
.
length
==
1
)
?
new
ArrayList
<>()
:
getTypeParam
(
tokens
[
1
],
lineCounter
,
prefix
[
0
].
length
()
==
includeRuleContext
.
length
()
-
1
,
mediateFile
);
lineCounter
,
prefix
[
0
].
equals
(
includeRuleContext
.
trim
())
,
mediateFile
);
imports
.
add
(
new
IncludeInfo
(
libName
,
typeParams
,
lineCounter
));
imports
.
add
(
new
IncludeInfo
(
libName
,
typeParams
,
lineCounter
));
}
else
if
(
str
.
contains
(
programBodyMark
))
{
}
else
if
(
str
.
contains
(
programBodyMark
))
{
bw
.
write
(
str
+
"\n"
);
bw
.
write
(
str
+
"\n"
);
...
@@ -158,7 +158,7 @@ public class PreCompiler {
...
@@ -158,7 +158,7 @@ public class PreCompiler {
if
(
str
.
contains
(
defineRuleContext
))
{
if
(
str
.
contains
(
defineRuleContext
))
{
/* get the lib's macro info, assume macros in stdlib are all valid */
/* get the lib's macro info, assume macros in stdlib are all valid */
String
[]
macro
=
str
.
split
(
" "
,
3
);
String
[]
macro
=
str
.
trim
().
split
(
" "
,
3
);
macros
.
add
(
new
MacroInfo
(
macro
[
1
],
macro
[
2
]));
macros
.
add
(
new
MacroInfo
(
macro
[
1
],
macro
[
2
]));
}
else
{
}
else
{
bw
.
write
(
" "
+
str
+
"\n"
);
/* copy the content */
bw
.
write
(
" "
+
str
+
"\n"
);
/* copy the content */
...
@@ -204,7 +204,11 @@ public class PreCompiler {
...
@@ -204,7 +204,11 @@ public class PreCompiler {
if
(
c
==
'<'
)
depth
++;
if
(
c
==
'<'
)
depth
++;
if
(
c
==
'>'
)
depth
--;
if
(
c
==
'>'
)
depth
--;
if
(
depth
==
0
)
{
if
(
c
==
'['
||
c
==
'('
)
{
mediateFile
.
delete
();
System
.
out
.
println
(
"Array or pair type are not supported: line "
+
lineNum
);
System
.
exit
(
SYNTAX_ERROR_CODE
);
}
else
if
(
depth
==
0
)
{
typeParams
.
add
(
token
.
toString
());
typeParams
.
add
(
token
.
toString
());
break
;
break
;
}
else
if
(
depth
==
1
&&
c
==
','
)
{
}
else
if
(
depth
==
1
&&
c
==
','
)
{
...
@@ -215,15 +219,7 @@ public class PreCompiler {
...
@@ -215,15 +219,7 @@ public class PreCompiler {
}
}
}
}
boolean
hasJunkAtEnd
=
false
;
if
(
i
!=
str
.
length
()
-
1
||
!
matchInclude
||
depth
!=
0
)
{
for
(
i
=
i
+
1
;
i
<
str
.
length
();
i
++)
{
if
(
str
.
charAt
(
i
)
!=
' '
)
{
hasJunkAtEnd
=
true
;
break
;
}
}
if
(
hasJunkAtEnd
||
!
matchInclude
||
depth
!=
0
)
{
mediateFile
.
delete
();
mediateFile
.
delete
();
System
.
out
.
println
(
"Invalid include statement at line "
+
lineNum
);
System
.
out
.
println
(
"Invalid include statement at line "
+
lineNum
);
System
.
exit
(
SYNTAX_ERROR_CODE
);
System
.
exit
(
SYNTAX_ERROR_CODE
);
...
...
src/backend/InstructionGenerator.java
View file @
01e6cfff
package
backend
;
package
backend
;
import
backend.arm.ARMInstructionGenerator
;
import
backend.arm.instructions.ARMInstruction
;
import
backend.common.LabelInstruction
;
import
backend.common.LabelInstruction
;
import
backend.intel.IntelInstructionGenerator
;
import
backend.intel.instructions.IntelInstruction
;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.List
;
import
utils.NodeVisitor
;
import
utils.NodeVisitor
;
import
utils.frontend.symbolTable.SymbolTable
;
import
utils.frontend.symbolTable.SymbolTable
;
public
abstract
class
InstructionGenerator
<
T
extends
Instruction
>
implements
NodeVisitor
<
Void
>
{
public
abstract
class
InstructionGenerator
<
T
extends
Instruction
>
implements
NodeVisitor
<
Void
>
{
/* the code section of the assembly code */
/* the code section of the assembly code */
protected
final
List
<
T
>
instructions
;
protected
final
List
<
T
>
instructions
;
/* record the current symbolTable used during instruction generation */
/* record the current symbolTable used during instruction generation */
...
@@ -32,6 +28,10 @@ public abstract class InstructionGenerator<T extends Instruction> implements Nod
...
@@ -32,6 +28,10 @@ public abstract class InstructionGenerator<T extends Instruction> implements Nod
protected
LabelInstruction
currBreakJumpToLabel
;
protected
LabelInstruction
currBreakJumpToLabel
;
protected
LabelInstruction
currContinueJumpToLabel
;
protected
LabelInstruction
currContinueJumpToLabel
;
/* used when a break/jump occure in a loop statment, accumulated on entering scope */
protected
int
breakSectionStackSize
;
protected
int
continueSectionStackSize
;
public
InstructionGenerator
()
{
public
InstructionGenerator
()
{
instructions
=
new
ArrayList
<>();
instructions
=
new
ArrayList
<>();
currSymbolTable
=
null
;
currSymbolTable
=
null
;
...
@@ -40,5 +40,7 @@ public abstract class InstructionGenerator<T extends Instruction> implements Nod
...
@@ -40,5 +40,7 @@ public abstract class InstructionGenerator<T extends Instruction> implements Nod
currBreakJumpToLabel
=
null
;
currBreakJumpToLabel
=
null
;
currContinueJumpToLabel
=
null
;
currContinueJumpToLabel
=
null
;
currForLoopSymbolTable
=
null
;
currForLoopSymbolTable
=
null
;
breakSectionStackSize
=
0
;
continueSectionStackSize
=
0
;
}
}
}
}
src/backend/InstructionPrinter.java
View file @
01e6cfff
package
backend
;
package
backend
;
public
abstract
class
InstructionPrinter
{
public
abstract
class
InstructionPrinter
{
public
abstract
String
translate
();
public
abstract
String
translate
();
}
}
src/backend/arm/ARMInstructionGenerator.java
View file @
01e6cfff
package
backend.arm
;
package
backend.arm
;
import
static
backend
.
arm
.
instructions
.
LDR
.
LdrMode
.*;
import
static
backend
.
arm
.
instructions
.
ARMInstructionRoutines
.
routineFunctionMap
;
import
static
backend
.
arm
.
instructions
.
STR
.
StrMode
.*;
import
static
backend
.
arm
.
instructions
.
LDR
.
LdrMode
.
LDR
;
import
static
backend
.
arm
.
instructions
.
addressing
.
AddressingMode2
.
AddrMode2
.*;
import
static
backend
.
arm
.
instructions
.
LDR
.
LdrMode
.
LDRSB
;
import
static
backend
.
arm
.
instructions
.
arithmeticLogic
.
ARMArithmeticLogic
.
armUnopAsm
;
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
.
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
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
.
RoutineInstruction
.*;
import
static
utils
.
Utils
.
RoutineInstruction
.
CHECK_ARRAY_BOUND
;
import
static
utils
.
Utils
.
SystemCallInstruction
.*;
import
static
utils
.
Utils
.
RoutineInstruction
.
CHECK_DIVIDE_BY_ZERO
;
import
static
utils
.
Utils
.*;
import
static
utils
.
Utils
.
RoutineInstruction
.
CHECK_NULL_POINTER
;
import
static
backend
.
arm
.
instructions
.
ARMInstructionRoutines
.
routineFunctionMap
;
import
static
utils
.
Utils
.
RoutineInstruction
.
FREE_ARRAY
;
import
static
utils
.
backend
.
Cond
.*;
import
static
utils
.
Utils
.
RoutineInstruction
.
FREE_PAIR
;
import
static
utils
.
backend
.
register
.
arm
.
ARMConcreteRegister
.*;
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.Instruction
;
import
backend.InstructionGenerator
;
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.LDR.LdrMode
;
import
backend.arm.instructions.
STR.StrMode
;
import
backend.arm.instructions.
LTORG
;
import
backend.arm.instructions.
addressing.*
;
import
backend.arm.instructions.
Label
;
import
backend.arm.instructions.
arithmeticLogic.*
;
import
backend.arm.instructions.
Mov
;
import
backend.arm.instructions.Pop
;
import
backend.arm.instructions.Pop
;
import
backend.arm.instructions.Push
;
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
backend.common.address.Address
;
import
frontend.node.*
;
import
frontend.node.FuncNode
;
import
frontend.node.expr.*
;
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.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.expr.UnopNode.Unop
;
import
frontend.node.stat.*
;
import
frontend.node.stat.AssignNode
;
import
frontend.node.stat.JumpNode.JumpContext
;
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.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.SwitchNode.CaseStat
;
import
frontend.node.stat.WhileNode
;
import
frontend.type.Type
;
import
frontend.type.Type
;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.Collections
;
...
@@ -42,12 +125,10 @@ import java.util.List;
...
@@ -42,12 +125,10 @@ import java.util.List;
import
java.util.Map
;
import
java.util.Map
;
import
java.util.Set
;
import
java.util.Set
;
import
java.util.stream.Collectors
;
import
java.util.stream.Collectors
;
import
utils.NodeVisitor
;
import
utils.backend.LabelGenerator
;
import
utils.backend.LabelGenerator
;
import
utils.backend.register.Register
;
import
utils.backend.register.arm.ARMConcreteRegister
;
import
utils.backend.register.arm.ARMConcreteRegister
;
import
utils.backend.register.arm.ARMConcreteRegisterAllocator
;
import
utils.backend.register.arm.ARMConcreteRegisterAllocator
;
import
utils.backend.register.Register
;
import
utils.frontend.symbolTable.SymbolTable
;
public
class
ARMInstructionGenerator
extends
InstructionGenerator
<
ARMInstruction
>
{
public
class
ARMInstructionGenerator
extends
InstructionGenerator
<
ARMInstruction
>
{
...
@@ -55,36 +136,27 @@ public class ARMInstructionGenerator extends InstructionGenerator<ARMInstruction
...
@@ -55,36 +136,27 @@ public class ARMInstructionGenerator extends InstructionGenerator<ARMInstruction
public
static
int
MAX_STACK_STEP
=
(
1
<<
10
);
public
static
int
MAX_STACK_STEP
=
(
1
<<
10
);
/* const used in visitBinop, for checking multiply overflow */
/* const used in visitBinop, for checking multiply overflow */
public
static
int
ASR_SHIFT_CONST
=
31
;
public
static
int
ASR_SHIFT_CONST
=
31
;
/* the ARM concrete register allocator */
private
final
ARMConcreteRegisterAllocator
armRegAllocator
;
/* the .data section of the assembly code */
/* the .data section of the assembly code */
protected
final
Map
<
Label
,
String
>
dataSegmentMessages
;
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
/* a list of instructions for storing different helper functions
* would be appended to the end of instructions list while printing */
* would be appended to the end of instructions list while printing */
private
final
List
<
ARMInstruction
>
ARMRoutines
;
private
final
List
<
ARMInstruction
>
ARMRoutines
;
/* record which helpers already exist, we don't want repeated helper functions */
/* record which helpers already exist, we don't want repeated helper functions */
private
final
Set
<
RoutineInstruction
>
alreadyExist
;
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 when a break/jump occure in a loop statment, accumulated on entering scope */
private
int
loopStackSize
;
/* used for mapping type with its print routine function */
/* used for mapping type with its print routine function */
private
final
Map
<
Type
,
RoutineInstruction
>
typeRoutineMap
=
Map
.
of
(
private
final
Map
<
Type
,
RoutineInstruction
>
typeRoutineMap
=
Map
.
of
(
INT_BASIC_TYPE
,
PRINT_INT
,
INT_BASIC_TYPE
,
PRINT_INT
,
CHAR_BASIC_TYPE
,
PRINT_CHAR
,
CHAR_BASIC_TYPE
,
PRINT_CHAR
,
BOOL_BASIC_TYPE
,
PRINT_BOOL
,
BOOL_BASIC_TYPE
,
PRINT_BOOL
,
STRING_BASIC_TYPE
,
PRINT_STRING
,
STRING_BASIC_TYPE
,
PRINT_STRING
,
CHAR_ARRAY_TYPE
,
PRINT_STRING
CHAR_ARRAY_TYPE
,
PRINT_STRING
);
);
/* recording the jump-to label for branching statement, i.e. break, continue */
private
Label
currBreakJumpToLabel
;
private
Label
currContinueJumpToLabel
;
public
ARMInstructionGenerator
()
{
public
ARMInstructionGenerator
()
{
super
();
super
();
...
@@ -143,7 +215,8 @@ public class ARMInstructionGenerator extends InstructionGenerator<ARMInstruction
...
@@ -143,7 +215,8 @@ public class ARMInstructionGenerator extends InstructionGenerator<ARMInstruction
/* visit the content */
/* visit the content */
for
(
int
i
=
0
;
i
<
node
.
getElemCount
();
i
++)
{
for
(
int
i
=
0
;
i
<
node
.
getElemCount
();
i
++)
{
visit
(
node
.
getElem
(
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
();
armRegAllocator
.
free
();
}
}
...
@@ -268,7 +341,7 @@ public class ARMInstructionGenerator extends InstructionGenerator<ARMInstruction
...
@@ -268,7 +341,7 @@ public class ARMInstructionGenerator extends InstructionGenerator<ARMInstruction
List
<
Instruction
>
insList
=
ARMArithmeticLogic
.
binopInstruction
List
<
Instruction
>
insList
=
ARMArithmeticLogic
.
binopInstruction
.
get
(
operator
)
.
get
(
operator
)
.
binopAssemble
(
e1reg
,
e
1
reg
,
op2
,
operator
);
.
binopAssemble
(
e1reg
,
e
2
reg
,
op2
,
operator
);
instructions
.
addAll
(
insList
.
stream
().
map
(
i
->
(
ARMInstruction
)
i
).
collect
(
Collectors
.
toList
()));
instructions
.
addAll
(
insList
.
stream
().
map
(
i
->
(
ARMInstruction
)
i
).
collect
(
Collectors
.
toList
()));
if
(
operator
==
Binop
.
DIV
||
operator
==
Binop
.
MOD
)
{
if
(
operator
==
Binop
.
DIV
||
operator
==
Binop
.
MOD
)
{
checkAndAddRoutine
(
CHECK_DIVIDE_BY_ZERO
,
msgLabelGenerator
,
dataSegmentMessages
);
checkAndAddRoutine
(
CHECK_DIVIDE_BY_ZERO
,
msgLabelGenerator
,
dataSegmentMessages
);
...
@@ -344,7 +417,8 @@ public class ARMInstructionGenerator extends InstructionGenerator<ARMInstruction
...
@@ -344,7 +417,8 @@ public class ARMInstructionGenerator extends InstructionGenerator<ARMInstruction
/* 2 call function with B instruction */
/* 2 call function with B instruction */
String
overloadName
=
node
.
getFunction
().
getOverloadName
();
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
));
instructions
.
add
(
new
BL
(
FUNC_HEADER
+
actualFuncName
));
/* 3 add back stack pointer */
/* 3 add back stack pointer */
...
@@ -677,7 +751,8 @@ public class ARMInstructionGenerator extends InstructionGenerator<ARMInstruction
...
@@ -677,7 +751,8 @@ public class ARMInstructionGenerator extends InstructionGenerator<ARMInstruction
/* accumulate function stack size, in case this scope is a function scope and contain return */
/* accumulate function stack size, in case this scope is a function scope and contain return */
funcStackSize
+=
stackSize
;
funcStackSize
+=
stackSize
;
loopStackSize
+=
stackSize
;
breakSectionStackSize
+=
stackSize
;
continueSectionStackSize
+=
stackSize
;
/* 2 visit statements
/* 2 visit statements
* set currentSymbolTable here, eliminate all other set symbol table in other statNode */
* set currentSymbolTable here, eliminate all other set symbol table in other statNode */
...
@@ -689,7 +764,8 @@ public class ARMInstructionGenerator extends InstructionGenerator<ARMInstruction
...
@@ -689,7 +764,8 @@ public class ARMInstructionGenerator extends InstructionGenerator<ARMInstruction
/* decrease function stack size, as from this point stack is freed by the scope, not by return */
/* decrease function stack size, as from this point stack is freed by the scope, not by return */
funcStackSize
-=
stackSize
;
funcStackSize
-=
stackSize
;
loopStackSize
-=
stackSize
;
breakSectionStackSize
-=
stackSize
;
continueSectionStackSize
-=
stackSize
;
/* 3 restore stack */
/* 3 restore stack */
incStack
(
stackSize
);
incStack
(
stackSize
);
...
@@ -716,22 +792,27 @@ public class ARMInstructionGenerator extends InstructionGenerator<ARMInstruction
...
@@ -716,22 +792,27 @@ public class ARMInstructionGenerator extends InstructionGenerator<ARMInstruction
Label
nextLabel
=
branchLabelGenerator
.
getLabel
().
asArmLabel
();
Label
nextLabel
=
branchLabelGenerator
.
getLabel
().
asArmLabel
();
/* restore the last jump-to label after visiting the while-loop body */
/* restore the last jump-to label after visiting the while-loop body */
Label
lastBreakJumpToLabel
=
currBreakJumpToLabel
;
Label
lastBreakJumpToLabel
=
Label
lastContinueJumpToLabel
=
currContinueJumpToLabel
;
currBreakJumpToLabel
==
null
?
null
:
currBreakJumpToLabel
.
asArmLabel
();
Label
lastContinueJumpToLabel
=
currContinueJumpToLabel
==
null
?
null
:
currContinueJumpToLabel
.
asArmLabel
();
currBreakJumpToLabel
=
nextLabel
;
currBreakJumpToLabel
=
nextLabel
;
currContinueJumpToLabel
=
testLabel
;
currContinueJumpToLabel
=
testLabel
;
instructions
.
add
(
startLabel
);
instructions
.
add
(
startLabel
);
/* record how much stack parent loop used */
/* record how much stack parent loop used */
int
prevLoopSize
=
loopStackSize
;
int
prevBreakLoopSize
=
breakSectionStackSize
;
loopStackSize
=
0
;
int
prevContinueLoopSize
=
continueSectionStackSize
;
breakSectionStackSize
=
0
;
continueSectionStackSize
=
0
;
/* 3 loop body */