Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
latte
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
zygzagZ
latte
Commits
9b245472
Commit
9b245472
authored
Jan 04, 2021
by
zygzagZ
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
quadcode względnie działa, brakuje flow zmiennych lokalnych między
blokami prostymi
parent
9f4bdacd
Changes
8
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
153 additions
and
72 deletions
+153
-72
Absyn.h
src/Absyn.h
+2
-0
Compiler.cpp
src/Compiler.cpp
+66
-48
Compiler.h
src/Compiler.h
+27
-1
Info.h
src/Info.h
+2
-1
TypeCheck.cpp
src/TypeCheck.cpp
+6
-3
TypeCheck.h
src/TypeCheck.h
+2
-0
Quadruple.h
src/codeGen/Quadruple.h
+29
-19
Variable.h
src/codeGen/Variable.h
+19
-0
No files found.
src/Absyn.h
View file @
9b245472
...
@@ -196,6 +196,8 @@ public:
...
@@ -196,6 +196,8 @@ public:
std
::
weak_ptr
<
FunctionInfo
>
function
;
std
::
weak_ptr
<
FunctionInfo
>
function
;
virtual
Block
*
clone
()
const
=
0
;
virtual
Block
*
clone
()
const
=
0
;
std
::
shared_ptr
<
Binding
>
getBinding
()
const
{
return
binding
;
};
};
};
class
Stmt
:
public
Visitable
class
Stmt
:
public
Visitable
...
...
src/Compiler.cpp
View file @
9b245472
...
@@ -130,13 +130,13 @@ void Compiler::visitNullCast(NullCast *p) {
...
@@ -130,13 +130,13 @@ void Compiler::visitNullCast(NullCast *p) {
void
Compiler
::
visitNeg
(
Neg
*
p
)
{
void
Compiler
::
visitNeg
(
Neg
*
p
)
{
auto
var
=
evalExpr
(
p
->
expr_
);
auto
var
=
evalExpr
(
p
->
expr_
);
lastVar
=
alloc
();
lastVar
=
alloc
();
quads
.
emplace_back
(
make_shared
<
QAssign
>
(
lastVar
,
Op
::
Neg
,
var
)
);
addQuad
<
QAssign
>
(
lastVar
,
Op
::
Neg
,
var
);
}
}
void
Compiler
::
visitNot
(
Not
*
p
)
{
void
Compiler
::
visitNot
(
Not
*
p
)
{
auto
var
=
evalExpr
(
p
->
expr_
);
auto
var
=
evalExpr
(
p
->
expr_
);
lastVar
=
alloc
();
lastVar
=
alloc
();
quads
.
emplace_back
(
make_shared
<
QAssign
>
(
lastVar
,
Op
::
Not
,
var
)
);
addQuad
<
QAssign
>
(
lastVar
,
Op
::
Not
,
var
);
}
}
// binary ops
// binary ops
...
@@ -146,7 +146,7 @@ void Compiler::visitEMul(EMul *p) {
...
@@ -146,7 +146,7 @@ void Compiler::visitEMul(EMul *p) {
auto
r
=
evalExpr
(
p
->
expr_2
);
auto
r
=
evalExpr
(
p
->
expr_2
);
lastVar
=
alloc
();
lastVar
=
alloc
();
p
->
mulop_
->
accept
(
this
);
p
->
mulop_
->
accept
(
this
);
quads
.
emplace_back
(
make_shared
<
QAssign
>
(
lastVar
,
l
,
op
,
r
)
);
addQuad
<
QAssign
>
(
lastVar
,
l
,
op
,
r
);
}
}
void
Compiler
::
visitEAdd
(
EAdd
*
p
)
{
void
Compiler
::
visitEAdd
(
EAdd
*
p
)
{
...
@@ -154,7 +154,7 @@ void Compiler::visitEAdd(EAdd *p) {
...
@@ -154,7 +154,7 @@ void Compiler::visitEAdd(EAdd *p) {
auto
r
=
evalExpr
(
p
->
expr_2
);
auto
r
=
evalExpr
(
p
->
expr_2
);
lastVar
=
alloc
();
lastVar
=
alloc
();
p
->
addop_
->
accept
(
this
);
p
->
addop_
->
accept
(
this
);
quads
.
emplace_back
(
make_shared
<
QAssign
>
(
lastVar
,
l
,
op
,
r
)
);
addQuad
<
QAssign
>
(
lastVar
,
l
,
op
,
r
);
}
}
...
@@ -163,7 +163,7 @@ void Compiler::visitERel(ERel *p) {
...
@@ -163,7 +163,7 @@ void Compiler::visitERel(ERel *p) {
auto
r
=
evalExpr
(
p
->
expr_2
);
auto
r
=
evalExpr
(
p
->
expr_2
);
lastVar
=
alloc
();
lastVar
=
alloc
();
p
->
relop_
->
accept
(
this
);
p
->
relop_
->
accept
(
this
);
quads
.
emplace_back
(
make_shared
<
QAssign
>
(
lastVar
,
l
,
op
,
r
)
);
addQuad
<
QAssign
>
(
lastVar
,
l
,
op
,
r
);
}
}
// lazy bools
// lazy bools
...
@@ -173,15 +173,15 @@ void Compiler::visitEAnd(EAnd *p) {
...
@@ -173,15 +173,15 @@ void Compiler::visitEAnd(EAnd *p) {
auto
labelLeft
=
make_shared
<
QLabel
>
(
"use_left"
);
auto
labelLeft
=
make_shared
<
QLabel
>
(
"use_left"
);
auto
labelAfter
=
make_shared
<
QLabel
>
(
"end_and"
);
auto
labelAfter
=
make_shared
<
QLabel
>
(
"end_and"
);
quads
.
emplace_back
(
make_shared
<
QJumpCond
>
(
labelLeft
,
Op
::
Not
,
l
)
);
addQuad
<
QJumpCond
>
(
labelLeft
,
Op
::
Not
,
l
);
auto
r
=
evalExpr
(
p
->
expr_2
);
auto
r
=
evalExpr
(
p
->
expr_2
);
lastVar
=
alloc
();
lastVar
=
alloc
();
quads
.
emplace_back
(
make_shared
<
QAssign
>
(
lastVar
,
Op
::
Copy
,
r
)
);
addQuad
<
QAssign
>
(
lastVar
,
Op
::
Copy
,
r
);
quads
.
emplace_back
(
make_shared
<
QJump
>
(
labelAfter
)
);
addQuad
<
QJump
>
(
labelAfter
);
quads
.
emplace_back
(
labelLeft
);
addQuad
(
labelLeft
);
quads
.
emplace_back
(
make_shared
<
QAssign
>
(
lastVar
,
Op
::
Copy
,
l
)
);
addQuad
<
QAssign
>
(
lastVar
,
Op
::
Copy
,
l
);
quads
.
emplace_back
(
labelAfter
);
addQuad
(
labelAfter
);
}
}
void
Compiler
::
visitEOr
(
EOr
*
p
)
{
void
Compiler
::
visitEOr
(
EOr
*
p
)
{
...
@@ -189,16 +189,16 @@ void Compiler::visitEOr(EOr *p) {
...
@@ -189,16 +189,16 @@ void Compiler::visitEOr(EOr *p) {
auto
labelLeft
=
make_shared
<
QLabel
>
(
"use_left"
);
auto
labelLeft
=
make_shared
<
QLabel
>
(
"use_left"
);
auto
labelAfter
=
make_shared
<
QLabel
>
(
"end_or"
);
auto
labelAfter
=
make_shared
<
QLabel
>
(
"end_or"
);
quads
.
emplace_back
(
make_shared
<
QJumpCond
>
(
labelLeft
,
Op
::
Copy
,
l
)
);
addQuad
<
QJumpCond
>
(
labelLeft
,
Op
::
Copy
,
l
);
auto
r
=
evalExpr
(
p
->
expr_2
);
auto
r
=
evalExpr
(
p
->
expr_2
);
lastVar
=
alloc
();
lastVar
=
alloc
();
quads
.
emplace_back
(
make_shared
<
QAssign
>
(
lastVar
,
Op
::
Copy
,
r
)
);
addQuad
<
QAssign
>
(
lastVar
,
Op
::
Copy
,
r
);
quads
.
emplace_back
(
make_shared
<
QJump
>
(
labelAfter
)
);
addQuad
<
QJump
>
(
labelAfter
);
quads
.
emplace_back
(
labelLeft
);
addQuad
(
labelLeft
);
quads
.
emplace_back
(
make_shared
<
QAssign
>
(
lastVar
,
Op
::
Copy
,
l
)
);
addQuad
<
QAssign
>
(
lastVar
,
Op
::
Copy
,
l
);
quads
.
emplace_back
(
labelAfter
);
addQuad
(
labelAfter
);
}
}
// complex extensions
// complex extensions
...
@@ -218,14 +218,14 @@ void Compiler::visitEIndexAcc(EIndexAcc *p) {
...
@@ -218,14 +218,14 @@ void Compiler::visitEIndexAcc(EIndexAcc *p) {
// calculate quantifier, we multiply index because size is larger than 4
// calculate quantifier, we multiply index because size is larger than 4
auto
q
=
alloc
(
type
->
type_
->
size
()
/
4
);
auto
q
=
alloc
(
type
->
type_
->
size
()
/
4
);
// calculate var = index * quantifier
// calculate var = index * quantifier
quads
.
emplace_back
(
make_shared
<
QAssign
>
(
lastVar
,
index
,
Op
::
Mul
,
q
)
);
addQuad
<
QAssign
>
(
lastVar
,
index
,
Op
::
Mul
,
q
);
// allocate new lastVar, index is now calculated multiplied index
// allocate new lastVar, index is now calculated multiplied index
index
=
alloc
();
index
=
alloc
();
swap
(
index
,
lastVar
);
swap
(
index
,
lastVar
);
}
}
auto
quad
=
make_shared
<
QAccess
>
(
lastVar
,
lhs
,
index
,
4
,
0
);
auto
quad
=
make_shared
<
QAccess
>
(
lastVar
,
lhs
,
index
,
4
,
0
);
quads
.
emplace_back
(
quad
);
addQuad
(
quad
);
}
}
void
Compiler
::
visitEClsMmbr
(
EClsMmbr
*
p
)
{
void
Compiler
::
visitEClsMmbr
(
EClsMmbr
*
p
)
{
...
@@ -234,18 +234,18 @@ void Compiler::visitEClsMmbr(EClsMmbr *p) {
...
@@ -234,18 +234,18 @@ void Compiler::visitEClsMmbr(EClsMmbr *p) {
assert
(
var
);
assert
(
var
);
// it cannot be function, as function might only be used in EApp and are handled directly there
// it cannot be function, as function might only be used in EApp and are handled directly there
assert
(
!
var
->
toFunction
());
assert
(
!
var
->
toFunction
());
// Array length calculation works because of arrayLengthVar that has offset 0
size_t
offset
=
var
->
offset
;
size_t
offset
=
var
->
offset
;
// TODO: Array length calculation
// if ()
if
(
dynamic_cast
<
EIndexAcc
*>
(
p
->
expr_
))
{
if
(
dynamic_cast
<
EIndexAcc
*>
(
p
->
expr_
))
{
// opt if EIndexAcc is used inside visitEClsMmbr
// opt if EIndexAcc is used inside visitEClsMmbr
auto
access
=
dynamic_pointer_cast
<
QAccess
>
(
quads
.
back
());
auto
access
=
dynamic_pointer_cast
<
QAccess
>
(
quads
.
back
());
access
->
offset
+=
offset
;
access
->
access
.
offset
+=
offset
;
l
->
info
=
var
;
lastVar
=
l
;
lastVar
=
l
;
}
else
{
}
else
{
lastVar
=
alloc
();
lastVar
=
alloc
(
var
);
auto
quad
=
make_shared
<
QAccess
>
(
lastVar
,
l
,
alloc
(
0
),
0
,
offset
);
auto
quad
=
make_shared
<
QAccess
>
(
lastVar
,
l
,
alloc
(
0
),
0
,
offset
);
quads
.
emplace_back
(
quad
);
addQuad
(
quad
);
}
}
}
}
...
@@ -280,15 +280,15 @@ void Compiler::visitEApp(EApp *p) {
...
@@ -280,15 +280,15 @@ void Compiler::visitEApp(EApp *p) {
int
i
=
1
;
int
i
=
1
;
for
(
auto
param
:
*
p
->
listexpr_
)
{
for
(
auto
param
:
*
p
->
listexpr_
)
{
auto
var
=
evalExpr
(
param
);
auto
var
=
evalExpr
(
param
);
quads
.
emplace_back
(
make_shared
<
QParam
>
(
var
,
i
++
)
);
addQuad
<
QParam
>
(
var
,
i
++
);
}
}
if
(
self
)
{
if
(
self
)
{
quads
.
emplace_back
(
make_shared
<
QParam
>
(
self
,
0
)
);
addQuad
<
QParam
>
(
self
,
0
);
}
}
lastVar
=
alloc
();
lastVar
=
alloc
();
quads
.
emplace_back
(
make_shared
<
QCall
>
(
lastVar
,
info
,
i
,
self
)
);
addQuad
<
QCall
>
(
lastVar
,
info
,
i
,
self
);
}
}
void
Compiler
::
visitENewArray
(
ENewArray
*
p
)
{
void
Compiler
::
visitENewArray
(
ENewArray
*
p
)
{
...
@@ -303,7 +303,7 @@ void Compiler::visitENewArray(ENewArray *p) {
...
@@ -303,7 +303,7 @@ void Compiler::visitENewArray(ENewArray *p) {
}
}
auto
count
=
evalExpr
(
p
->
expr_
);
auto
count
=
evalExpr
(
p
->
expr_
);
lastVar
=
alloc
();
lastVar
=
alloc
();
quads
.
emplace_back
(
make_shared
<
QAlloc
>
(
lastVar
,
size
,
virtSymbol
,
count
)
);
addQuad
<
QAlloc
>
(
lastVar
,
size
,
virtSymbol
,
count
);
}
}
void
Compiler
::
visitENewClass
(
ENewClass
*
p
)
{
void
Compiler
::
visitENewClass
(
ENewClass
*
p
)
{
...
@@ -312,7 +312,7 @@ void Compiler::visitENewClass(ENewClass *p) {
...
@@ -312,7 +312,7 @@ void Compiler::visitENewClass(ENewClass *p) {
size_t
size
=
info
->
size
;
size_t
size
=
info
->
size
;
std
::
string
virtSymbol
=
getVirtName
(
info
);
std
::
string
virtSymbol
=
getVirtName
(
info
);
lastVar
=
alloc
();
lastVar
=
alloc
();
quads
.
emplace_back
(
make_shared
<
QAlloc
>
(
lastVar
,
size
,
virtSymbol
)
);
addQuad
<
QAlloc
>
(
lastVar
,
size
,
virtSymbol
);
}
}
/// statements
/// statements
...
@@ -321,35 +321,53 @@ void Compiler::visitInit(Init *p) {
...
@@ -321,35 +321,53 @@ void Compiler::visitInit(Init *p) {
auto
info
=
p
->
pident_
->
var
.
lock
();
auto
info
=
p
->
pident_
->
var
.
lock
();
assert
(
info
);
assert
(
info
);
auto
var
=
evalExpr
(
p
->
expr_
);
auto
var
=
evalExpr
(
p
->
expr_
);
quads
.
emplace_back
(
make_shared
<
QAssign
>
(
alloc
(
info
),
Op
::
Copy
,
var
));
addQuad
<
QAssign
>
(
alloc
(
info
),
Op
::
Copy
,
var
);
}
void
Compiler
::
assign
(
Expr
*
lval
,
VariablePtr
val
)
{
auto
dest
=
evalLVal
(
lval
);
if
(
dest
->
info
&&
dest
->
info
->
isInstanceVariable
())
{
// instance variable, need to write it to memory
auto
quad
=
dynamic_pointer_cast
<
QAccess
>
(
quads
.
empty
()
?
nullptr
:
quads
.
back
());
assert
(
quad
);
auto
loc
=
quad
->
access
;
quads
.
pop_back
();
addQuad
<
QWrite
>
(
loc
,
val
);
return
;
}
else
{
// local variable - only assign
addQuad
<
QAssign
>
(
dest
,
Op
::
Copy
,
val
);
}
}
}
void
Compiler
::
visitAss
(
Ass
*
p
)
{
void
Compiler
::
visitAss
(
Ass
*
p
)
{
auto
dest
=
evalExpr
(
p
->
expr_1
);
auto
val
=
evalExpr
(
p
->
expr_2
);
quads
.
emplace_back
(
make_shared
<
QAssign
>
(
dest
,
Op
::
Copy
,
evalExpr
(
p
->
expr_2
))
);
assign
(
p
->
expr_1
,
val
);
}
}
void
Compiler
::
visitIncr
(
Incr
*
p
)
{
void
Compiler
::
visitIncr
(
Incr
*
p
)
{
auto
dest
=
evalExpr
(
p
->
expr_
);
auto
lhs
=
evalExpr
(
p
->
expr_
);
auto
lhs
=
evalExpr
(
p
->
expr_
);
quads
.
emplace_back
(
make_shared
<
QAssign
>
(
dest
,
lhs
,
Op
::
Plus
,
alloc
(
1
)));
auto
tmp
=
alloc
();
addQuad
<
QAssign
>
(
tmp
,
lhs
,
Op
::
Plus
,
alloc
(
1
));
assign
(
p
->
expr_
,
tmp
);
}
}
void
Compiler
::
visitDecr
(
Decr
*
p
)
{
void
Compiler
::
visitDecr
(
Decr
*
p
)
{
auto
dest
=
evalExpr
(
p
->
expr_
);
auto
lhs
=
evalExpr
(
p
->
expr_
);
auto
lhs
=
evalExpr
(
p
->
expr_
);
quads
.
emplace_back
(
make_shared
<
QAssign
>
(
dest
,
lhs
,
Op
::
Minus
,
alloc
(
1
)));
auto
tmp
=
alloc
();
addQuad
<
QAssign
>
(
tmp
,
lhs
,
Op
::
Minus
,
alloc
(
1
));
assign
(
p
->
expr_
,
tmp
);
}
}
void
Compiler
::
visitRet
(
Ret
*
p
)
{
void
Compiler
::
visitRet
(
Ret
*
p
)
{
auto
var
=
evalExpr
(
p
->
expr_
);
auto
var
=
evalExpr
(
p
->
expr_
);
endBasicBlock
();
endBasicBlock
();
quads
.
emplace_back
(
make_shared
<
QReturn
>
(
var
)
);
addQuad
<
QReturn
>
(
var
);
}
}
void
Compiler
::
visitVRet
(
VRet
*
p
)
{
void
Compiler
::
visitVRet
(
VRet
*
p
)
{
endBasicBlock
();
endBasicBlock
();
quads
.
emplace_back
(
make_shared
<
QReturn
>
(
nullptr
)
);
addQuad
<
QReturn
>
(
nullptr
);
}
}
void
Compiler
::
visitCond
(
Cond
*
p
)
{
void
Compiler
::
visitCond
(
Cond
*
p
)
{
...
@@ -357,11 +375,11 @@ void Compiler::visitCond(Cond *p) {
...
@@ -357,11 +375,11 @@ void Compiler::visitCond(Cond *p) {
auto
after
=
make_shared
<
QLabel
>
(
"end_if"
);
auto
after
=
make_shared
<
QLabel
>
(
"end_if"
);
endBasicBlock
();
// possible jump -> after
endBasicBlock
();
// possible jump -> after
quads
.
emplace_back
(
make_shared
<
QJumpCond
>
(
after
,
Op
::
Not
,
var
)
);
addQuad
<
QJumpCond
>
(
after
,
Op
::
Not
,
var
);
p
->
stmt_
->
accept
(
this
);
p
->
stmt_
->
accept
(
this
);
endBasicBlock
();
// possible jump <- cond
endBasicBlock
();
// possible jump <- cond
quads
.
emplace_back
(
after
);
addQuad
(
after
);
}
}
void
Compiler
::
visitCondElse
(
CondElse
*
p
)
{
void
Compiler
::
visitCondElse
(
CondElse
*
p
)
{
...
@@ -371,36 +389,36 @@ void Compiler::visitCondElse(CondElse *p) {
...
@@ -371,36 +389,36 @@ void Compiler::visitCondElse(CondElse *p) {
auto
var
=
evalExpr
(
p
->
expr_
);
auto
var
=
evalExpr
(
p
->
expr_
);
endBasicBlock
();
// possible jump -> else
endBasicBlock
();
// possible jump -> else
quads
.
emplace_back
(
make_shared
<
QJumpCond
>
(
elseBranch
,
Op
::
Not
,
var
)
);
addQuad
<
QJumpCond
>
(
elseBranch
,
Op
::
Not
,
var
);
p
->
stmt_1
->
accept
(
this
);
p
->
stmt_1
->
accept
(
this
);
endBasicBlock
();
// jump -> after
endBasicBlock
();
// jump -> after
quads
.
emplace_back
(
make_shared
<
QJump
>
(
after
)
);
addQuad
<
QJump
>
(
after
);
quads
.
emplace_back
(
elseBranch
);
addQuad
(
elseBranch
);
p
->
stmt_2
->
accept
(
this
);
p
->
stmt_2
->
accept
(
this
);
endBasicBlock
();
// jump <- cond
endBasicBlock
();
// jump <- cond
quads
.
emplace_back
(
after
);
addQuad
(
after
);
}
}
void
Compiler
::
visitWhile
(
While
*
p
)
{
void
Compiler
::
visitWhile
(
While
*
p
)
{
auto
cond
=
make_shared
<
QLabel
>
(
"cond"
);
auto
cond
=
make_shared
<
QLabel
>
(
"cond"
);
endBasicBlock
();
// jump <- loop -> cond
endBasicBlock
();
// jump <- loop -> cond
quads
.
emplace_back
(
make_shared
<
QJump
>
(
cond
)
);
addQuad
<
QJump
>
(
cond
);
// jump <- loop
// jump <- loop
auto
loop
=
make_shared
<
QLabel
>
(
"loop"
);
auto
loop
=
make_shared
<
QLabel
>
(
"loop"
);
quads
.
emplace_back
(
loop
);
addQuad
(
loop
);
p
->
stmt_
->
accept
(
this
);
p
->
stmt_
->
accept
(
this
);
endBasicBlock
();
// jump <- cond
endBasicBlock
();
// jump <- cond
quads
.
emplace_back
(
cond
);
addQuad
(
cond
);
auto
var
=
evalExpr
(
p
->
expr_
);
auto
var
=
evalExpr
(
p
->
expr_
);
endBasicBlock
();
// jump -> loop
endBasicBlock
();
// jump -> loop
quads
.
emplace_back
(
make_shared
<
QJumpCond
>
(
loop
,
Op
::
Copy
,
var
)
);
addQuad
<
QJumpCond
>
(
loop
,
Op
::
Copy
,
var
);
}
}
void
Compiler
::
visitSExp
(
SExp
*
p
)
{
void
Compiler
::
visitSExp
(
SExp
*
p
)
{
...
...
src/Compiler.h
View file @
9b245472
...
@@ -31,11 +31,22 @@ private:
...
@@ -31,11 +31,22 @@ private:
Quadruple
::
Op
op
;
Quadruple
::
Op
op
;
VariablePtr
lastVar
;
VariablePtr
lastVar
;
int
lineno
;
void
compileFunction
(
FunctionInfoPtr
f
);
void
compileFunction
(
FunctionInfoPtr
f
);
VariablePtr
evalLVal
(
Visitable
*
expr
)
{
auto
info
=
evalExpr
(
expr
)
->
info
;
if
(
!
info
)
{
throw
ParseError
(
"LValue expected"
,
expr
);
}
info
->
loc
=
nullptr
;
return
alloc
(
info
);
}
VariablePtr
evalExpr
(
Visitable
*
expr
)
{
VariablePtr
evalExpr
(
Visitable
*
expr
)
{
if
(
!
expr
)
throw
runtime_error
(
"No expr to eval"
);
if
(
!
expr
)
throw
runtime_error
(
"No expr to eval"
);
lineno
=
expr
->
lineno
;
lastVar
=
nullptr
;
lastVar
=
nullptr
;
try
{
try
{
expr
->
accept
(
this
);
expr
->
accept
(
this
);
...
@@ -60,7 +71,7 @@ private:
...
@@ -60,7 +71,7 @@ private:
};
};
VariablePtr
alloc
(
VarInfoPtr
info
)
{
VariablePtr
alloc
(
VarInfoPtr
info
)
{
if
(
info
->
loc
)
{
if
(
info
->
loc
&&
!
info
->
isInstanceVariable
()
)
{
return
info
->
loc
;
return
info
->
loc
;
}
}
auto
v
=
make_shared
<
Variable
>
(
info
);
auto
v
=
make_shared
<
Variable
>
(
info
);
...
@@ -74,8 +85,23 @@ private:
...
@@ -74,8 +85,23 @@ private:
return
v
;
return
v
;
}
}
template
<
typename
T
,
typename
...
Args
>
QuadruplePtr
addQuad
(
Args
...
args
)
{
auto
quad
=
make_shared
<
T
>
(
args
...);
quad
->
lineno
=
lineno
;
quads
.
emplace_back
(
quad
);
return
quad
;
}
QuadruplePtr
addQuad
(
QuadruplePtr
quad
)
{
quad
->
lineno
=
lineno
;
quads
.
emplace_back
(
quad
);
return
quad
;
}
void
endBasicBlock
();
void
endBasicBlock
();
void
assign
(
Expr
*
lval
,
VariablePtr
val
);
void
visitEVar
(
EVar
*
p
)
override
;
void
visitEVar
(
EVar
*
p
)
override
;
void
visitEIndexAcc
(
EIndexAcc
*
p
)
override
;
void
visitEIndexAcc
(
EIndexAcc
*
p
)
override
;
void
visitEClsMmbr
(
EClsMmbr
*
p
)
override
;
void
visitEClsMmbr
(
EClsMmbr
*
p
)
override
;
...
...
src/Info.h
View file @
9b245472
...
@@ -26,7 +26,8 @@ public:
...
@@ -26,7 +26,8 @@ public:
string
name
;
string
name
;
TypePtr
type
;
TypePtr
type
;
int
lineLocation
;
int
lineLocation
;
size_t
offset
;
size_t
offset
=
0
;
bool
isInstanceVariable
()
const
{
return
offset
;
};
VariablePtr
loc
;
VariablePtr
loc
;
...
...
src/TypeCheck.cpp
View file @
9b245472
...
@@ -117,7 +117,7 @@ void TypeCheck::visitClassFld(ClassFld *decl)
...
@@ -117,7 +117,7 @@ void TypeCheck::visitClassFld(ClassFld *decl)
void
TypeCheck
::
visitBlk
(
Blk
*
blk
)
void
TypeCheck
::
visitBlk
(
Blk
*
blk
)
{
{
BindingPtr
binding
=
blk
->
binding
/*.lock()*/
;
BindingPtr
binding
=
blk
->
getBinding
()
;
if
(
!
binding
)
{
if
(
!
binding
)
{
binding
=
make_shared
<
Binding
>
(
scope
->
currentBinding
);
binding
=
make_shared
<
Binding
>
(
scope
->
currentBinding
);
blk
->
binding
=
binding
;
blk
->
binding
=
binding
;
...
@@ -310,8 +310,9 @@ void TypeCheck::visitEClsMmbr(EClsMmbr *e_cls_mmbr)
...
@@ -310,8 +310,9 @@ void TypeCheck::visitEClsMmbr(EClsMmbr *e_cls_mmbr)
if
(
!
type
)
{
if
(
!
type
)
{
// it is an array and we ask for length
// it is an array and we ask for length
if
(
dynamic_pointer_cast
<
Array
>
(
exprType
))
{
if
(
dynamic_pointer_cast
<
Array
>
(
exprType
))
{
if
(
e_cls_mmbr
->
pident_
->
string_
==
"length"
)
{
if
(
e_cls_mmbr
->
pident_
->
string_
==
arrayLengthVar
->
name
)
{
lastType
=
make_shared
<
Int
>
();
e_cls_mmbr
->
pident_
->
var
=
arrayLengthVar
;
lastType
=
arrayLengthVar
->
type
;
return
;
return
;
}
}
}
}
...
@@ -558,6 +559,8 @@ void TypeCheck::setupEnv() {
...
@@ -558,6 +559,8 @@ void TypeCheck::setupEnv() {
scope
->
functions
<<
error
;
scope
->
functions
<<
error
;
}
}
arrayLengthVar
=
make_shared
<
VarInfo
>
(
"length"
,
make_shared
<
Int
>
());
}
}
void
TypeCheck
::
check
(
Visitable
*
v
)
void
TypeCheck
::
check
(
Visitable
*
v
)
...
...
src/TypeCheck.h
View file @
9b245472
...
@@ -22,6 +22,8 @@ class TypeCheck : public Visitor
...
@@ -22,6 +22,8 @@ class TypeCheck : public Visitor
vector
<
pair
<
ClassInfoPtr
,
ClassDef
*>>
classDefs
;
vector
<
pair
<
ClassInfoPtr
,
ClassDef
*>>
classDefs
;
VarInfoPtr
arrayLengthVar
;
void
checkFunction
(
FunctionInfoPtr
f
);
void
checkFunction
(
FunctionInfoPtr
f
);
void
checkReturnStatement
(
shared_ptr
<
Type
>
type
,
Stmt
*
stmt
);
void
checkReturnStatement
(
shared_ptr
<
Type
>
type
,
Stmt
*
stmt
);
void
checkFunctionRet
();
void
checkFunctionRet
();
...
...
src/codeGen/Quadruple.h
View file @
9b245472
...
@@ -38,8 +38,10 @@ public:
...
@@ -38,8 +38,10 @@ public:
}
}
};
};
int
lineno
;
virtual
~
Quadruple
()
{};
virtual
~
Quadruple
()
{};
virtual
std
::
string
toString
()
const
=
0
;
virtual
std
::
string
toString
()
const
{
return
to_string
(
lineno
)
+
"
\t
"
;
}
;
};
};
class
QWriteVar
:
public
Quadruple
{
class
QWriteVar
:
public
Quadruple
{
...
@@ -47,13 +49,13 @@ public:
...
@@ -47,13 +49,13 @@ public:
VariablePtr
loc
;
VariablePtr
loc
;
explicit
QWriteVar
(
VariablePtr
loc
)
:
Quadruple
(),
loc
(
std
::
move
(
loc
))
{};
explicit
QWriteVar
(
VariablePtr
loc
)
:
Quadruple
(),
loc
(
std
::
move
(
loc
))
{};
std
::
string
toString
()
const
override
{
return
loc
?
(
"
\t
"
+
loc
->
name
+
" := "
)
:
"
\t
"
;
}
std
::
string
toString
()
const
override
{
return
Quadruple
::
toString
()
+
"
\t
"
+
(
loc
?
(
loc
->
name
+
" := "
)
:
""
)
;
}
};
};
class
QLabel
:
public
Quadruple
{
class
QLabel
:
public
Quadruple
{
public:
public:
string
label
;
string
label
;
std
::
string
toString
()
const
override
{
return
"
\"
"
+
label
+
"
\"
:"
;
}
std
::
string
toString
()
const
override
{
return
Quadruple
::
toString
()
+
"
\"
"
+
label
+
"
\"
:"
;
}
QLabel
(
std
::
string
comment
)
:
label
(
comment
)
{}
QLabel
(
std
::
string
comment
)
:
label
(
comment
)
{}
};
};
...
@@ -80,7 +82,7 @@ public:
...
@@ -80,7 +82,7 @@ public:
explicit
QJump
(
shared_ptr
<
QLabel
>
target
)
:
target
(
std
::
move
(
target
))
{};
explicit
QJump
(
shared_ptr
<
QLabel
>
target
)
:
target
(
std
::
move
(
target
))
{};
std
::
string
toString
()
const
override
{
std
::
string
toString
()
const
override
{
return
"
\t
jump "
+
target
->
label
;
return
Quadruple
::
toString
()
+
"
jump "
+
target
->
label
;
}
}
};
};
...
@@ -97,9 +99,9 @@ public:
...
@@ -97,9 +99,9 @@ public:
std
::
string
toString
()
const
override
{
std
::
string
toString
()
const
override
{
if
(
!
left
)
if
(
!
left
)
return
"
\t
jump
\"
"
+
target
->
label
+
"
\"
if "
+
Op
::
name
(
op
)
+
" "
+
right
->
name
;
return
Quadruple
::
toString
()
+
"
jump
\"
"
+
target
->
label
+
"
\"
if "
+
Op
::
name
(
op
)
+
" "
+
right
->
name
;
else
else
return
"
\t
jump
\"
"
+
target
->
label
+
"
\"
if "
+
left
->
name
+
" "
+
Op
::
name
(
op
)
+
" "
+
right
->
name
;
return
Quadruple
::
toString
()
+
"
jump
\"
"
+
target
->
label
+
"
\"
if "
+
left
->
name
+
" "
+
Op
::
name
(
op
)
+
" "
+
right
->
name
;
}
}
};
};
...
@@ -112,9 +114,9 @@ public:
...
@@ -112,9 +114,9 @@ public:
std
::
string
toString
()
const
override
{
std
::
string
toString
()
const
override
{
if
(
num
==
0
)
{
if
(
num
==
0
)
{
return
"
\t
param self "
+
param
->
name
;
return
Quadruple
::
toString
()
+
"
\t
param self "
+
param
->
name
;
}
else
{
}
else
{
return
"
\t
param #"
+
to_string
(
num
)
+
" <- "
+
param
->
name
;
return
Quadruple
::
toString
()
+
"
\t
param #"
+
to_string
(
num
)
+
" <- "
+
param
->
name
;
}
}
}
}
};
};
...
@@ -143,9 +145,9 @@ public:
...
@@ -143,9 +145,9 @@ public:
std
::
string
toString
()
const
override
{
std
::
string
toString
()
const
override
{
if
(
ret
)
{
if
(
ret
)
{
return
"
\t
return "
+
ret
->
name
;
return
Quadruple
::
toString
()
+
"
\t
return "
+
ret
->
name
;
}
else
{
}
else
{
return
"
\t
return"
;
return
Quadruple
::
toString
()
+
"
\t
return"
;
}
}
}
}
};
};
...
@@ -153,23 +155,31 @@ public:
...
@@ -153,23 +155,31 @@ public:
class
QAccess
:
public
QWriteVar
{
class
QAccess
:
public
QWriteVar
{
public:
public:
QAccess
(
VariablePtr
loc
,
VariablePtr
base
,
VariablePtr
index
,
int
multiplier
,
int
offset
)
QAccess
(
VariablePtr
loc
,
VariablePtr
base
,
VariablePtr
index
,
int
multiplier
,
int
offset
)
:
QWriteVar
(
std
::
move
(
loc
)),
base
(
std
::
move
(
base
)),
index
(
std
::
move
(
index
)),
multiplier
(
multiplier
),
offset
(
offset
)
:
QWriteVar
(
std
::
move
(
loc
)),
access
(
std
::
move
(
base
),
std
::
move
(
index
),
multiplier
,
offset
)
{};
{};
// leal 8(,%eax,4), %eax # Arithmetic: multiply eax by 4 and add 8
// leal 8(,%eax,4), %eax # Arithmetic: multiply eax by 4 and add 8
// leal (%edx,%eax,2), %eax # Arithmetic: multiply eax by 2 and add edx
// leal (%edx,%eax,2), %eax # Arithmetic: multiply eax by 2 and add edx
VariablePtr
base
;
VariableLocation
access
;
VariablePtr
index
;
bool
lea
=
false
;
int
multiplier
;
int
offset
;
std
::
string
toString
()
const
override
{
std
::
string
toString
()
const
override
{
auto
ret
=
QWriteVar
::
toString
()
+
"["
+
base
->
name
;
auto
ret
=
QWriteVar
::
toString
();
if
(
multiplier
||
!
(
index
->
constExpr
||
!
index
->
val
))
ret
+=
" + "
+
to_string
(
multiplier
)
+
"*"
+
index
->
name
;
if
(
lea
)
ret
+=
"&"
;
if
(
offset
)
ret
+=
" + "
+
to_string
(
offset
);
return
ret
+
access
.
toString
();
return
ret
+
"]"
;
}
}
};
};
class
QWrite
:
public
Quadruple
{
public:
QWrite
(
VariableLocation
loc
,
VariablePtr
val
)
:
Quadruple
(),
loc
(
std
::
move
(
loc
)),
val
(
std
::
move
(
val
))
{};
VariableLocation
loc
;
VariablePtr
val
;
std
::
string
toString
()
const
override
{
return
Quadruple
::
toString
()
+
"
\t
"
+
loc
.
toString
()
+
" := "
+
val
->
name
;
}
};
class
QAlloc
:
public
QWriteVar
{
class
QAlloc
:
public
QWriteVar
{
public:
public:
size_t
size
;
size_t
size
;
...
...
src/codeGen/Variable.h
View file @
9b245472
...
@@ -27,4 +27,23 @@ public:
...
@@ -27,4 +27,23 @@ public:
// where in mem - id or offset
// where in mem - id or offset
};
};
class
VariableLocation
{
public:
VariableLocation
()
=
default
;
VariableLocation
(
VariablePtr
base
,
VariablePtr
index
,
int
multiplier
,
int
offset
)
:
base
(
std
::
move
(
base
)),
index
(
std
::
move
(
index
)),
multiplier
(
multiplier
),
offset
(
offset
)
{}
VariablePtr
base
;
VariablePtr
index
;
int
multiplier
;
int
offset
;
string
toString
()
const
{
std
::
string
ret
=
"["
+
base
->
name
;
if
(
multiplier
||
!
(
index
->
constExpr
||
!
index
->
val
))
ret
+=
" + "
+
to_string
(
multiplier
)
+
"*"
+
index
->
name
;
if
(
offset
)
ret
+=
" + "
+
to_string
(
offset
);
return
ret
+
"]"
;
}
};
#endif //ZAD2_VARIABLE_H
#endif //ZAD2_VARIABLE_H
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment