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
Hide 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:
std
::
weak_ptr
<
FunctionInfo
>
function
;
virtual
Block
*
clone
()
const
=
0
;
std
::
shared_ptr
<
Binding
>
getBinding
()
const
{
return
binding
;
};
};
class
Stmt
:
public
Visitable
...
...
src/Compiler.cpp
View file @
9b245472
...
...
@@ -130,13 +130,13 @@ void Compiler::visitNullCast(NullCast *p) {
void
Compiler
::
visitNeg
(
Neg
*
p
)
{
auto
var
=
evalExpr
(
p
->
expr_
);
lastVar
=
alloc
();
quads
.
emplace_back
(
make_shared
<
QAssign
>
(
lastVar
,
Op
::
Neg
,
var
)
);
addQuad
<
QAssign
>
(
lastVar
,
Op
::
Neg
,
var
);
}
void
Compiler
::
visitNot
(
Not
*
p
)
{
auto
var
=
evalExpr
(
p
->
expr_
);
lastVar
=
alloc
();
quads
.
emplace_back
(
make_shared
<
QAssign
>
(
lastVar
,
Op
::
Not
,
var
)
);
addQuad
<
QAssign
>
(
lastVar
,
Op
::
Not
,
var
);
}
// binary ops
...
...
@@ -146,7 +146,7 @@ void Compiler::visitEMul(EMul *p) {
auto
r
=
evalExpr
(
p
->
expr_2
);
lastVar
=
alloc
();
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
)
{
...
...
@@ -154,7 +154,7 @@ void Compiler::visitEAdd(EAdd *p) {
auto
r
=
evalExpr
(
p
->
expr_2
);
lastVar
=
alloc
();
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) {
auto
r
=
evalExpr
(
p
->
expr_2
);
lastVar
=
alloc
();
p
->
relop_
->
accept
(
this
);
quads
.
emplace_back
(
make_shared
<
QAssign
>
(
lastVar
,
l
,
op
,
r
)
);
addQuad
<
QAssign
>
(
lastVar
,
l
,
op
,
r
);
}
// lazy bools
...
...
@@ -173,15 +173,15 @@ void Compiler::visitEAnd(EAnd *p) {
auto
labelLeft
=
make_shared
<
QLabel
>
(
"use_left"
);
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
);
lastVar
=
alloc
();
quads
.
emplace_back
(
make_shared
<
QAssign
>
(
lastVar
,
Op
::
Copy
,
r
)
);
quads
.
emplace_back
(
make_shared
<
QJump
>
(
labelAfter
)
);
quads
.
emplace_back
(
labelLeft
);
quads
.
emplace_back
(
make_shared
<
QAssign
>
(
lastVar
,
Op
::
Copy
,
l
)
);
quads
.
emplace_back
(
labelAfter
);
addQuad
<
QAssign
>
(
lastVar
,
Op
::
Copy
,
r
);
addQuad
<
QJump
>
(
labelAfter
);
addQuad
(
labelLeft
);
addQuad
<
QAssign
>
(
lastVar
,
Op
::
Copy
,
l
);
addQuad
(
labelAfter
);
}
void
Compiler
::
visitEOr
(
EOr
*
p
)
{
...
...
@@ -189,16 +189,16 @@ void Compiler::visitEOr(EOr *p) {
auto
labelLeft
=
make_shared
<
QLabel
>
(
"use_left"
);
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
);
lastVar
=
alloc
();
quads
.
emplace_back
(
make_shared
<
QAssign
>
(
lastVar
,
Op
::
Copy
,
r
)
);
quads
.
emplace_back
(
make_shared
<
QJump
>
(
labelAfter
)
);
quads
.
emplace_back
(
labelLeft
);
quads
.
emplace_back
(
make_shared
<
QAssign
>
(
lastVar
,
Op
::
Copy
,
l
)
);
quads
.
emplace_back
(
labelAfter
);
addQuad
<
QAssign
>
(
lastVar
,
Op
::
Copy
,
r
);
addQuad
<
QJump
>
(
labelAfter
);
addQuad
(
labelLeft
);
addQuad
<
QAssign
>
(
lastVar
,
Op
::
Copy
,
l
);
addQuad
(
labelAfter
);
}
// complex extensions
...
...
@@ -218,14 +218,14 @@ void Compiler::visitEIndexAcc(EIndexAcc *p) {
// calculate quantifier, we multiply index because size is larger than 4
auto
q
=
alloc
(
type
->
type_
->
size
()
/
4
);
// 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
index
=
alloc
();
swap
(
index
,
lastVar
);
}
auto
quad
=
make_shared
<
QAccess
>
(
lastVar
,
lhs
,
index
,
4
,
0
);
quads
.
emplace_back
(
quad
);
addQuad
(
quad
);
}
void
Compiler
::
visitEClsMmbr
(
EClsMmbr
*
p
)
{
...
...
@@ -234,18 +234,18 @@ void Compiler::visitEClsMmbr(EClsMmbr *p) {
assert
(
var
);
// it cannot be function, as function might only be used in EApp and are handled directly there
assert
(
!
var
->
toFunction
());
// Array length calculation works because of arrayLengthVar that has offset 0
size_t
offset
=
var
->
offset
;
// TODO: Array length calculation
// if ()
if
(
dynamic_cast
<
EIndexAcc
*>
(
p
->
expr_
))
{
// opt if EIndexAcc is used inside visitEClsMmbr
auto
access
=
dynamic_pointer_cast
<
QAccess
>
(
quads
.
back
());
access
->
offset
+=
offset
;
access
->
access
.
offset
+=
offset
;
l
->
info
=
var
;
lastVar
=
l
;
}
else
{
lastVar
=
alloc
();
lastVar
=
alloc
(
var
);
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) {
int
i
=
1
;
for
(
auto
param
:
*
p
->
listexpr_
)
{
auto
var
=
evalExpr
(
param
);
quads
.
emplace_back
(
make_shared
<
QParam
>
(
var
,
i
++
)
);
addQuad
<
QParam
>
(
var
,
i
++
);
}
if
(
self
)
{
quads
.
emplace_back
(
make_shared
<
QParam
>
(
self
,
0
)
);
addQuad
<
QParam
>
(
self
,
0
);
}
lastVar
=
alloc
();
quads
.
emplace_back
(
make_shared
<
QCall
>
(
lastVar
,
info
,
i
,
self
)
);
addQuad
<
QCall
>
(
lastVar
,
info
,
i
,
self
);
}
void
Compiler
::
visitENewArray
(
ENewArray
*
p
)
{
...
...
@@ -303,7 +303,7 @@ void Compiler::visitENewArray(ENewArray *p) {
}
auto
count
=
evalExpr
(
p
->
expr_
);
lastVar
=
alloc
();
quads
.
emplace_back
(
make_shared
<
QAlloc
>
(
lastVar
,
size
,
virtSymbol
,
count
)
);
addQuad
<
QAlloc
>
(
lastVar
,
size
,
virtSymbol
,
count
);
}
void
Compiler
::
visitENewClass
(
ENewClass
*
p
)
{
...
...
@@ -312,7 +312,7 @@ void Compiler::visitENewClass(ENewClass *p) {
size_t
size
=
info
->
size
;
std
::
string
virtSymbol
=
getVirtName
(
info
);
lastVar
=
alloc
();
quads
.
emplace_back
(
make_shared
<
QAlloc
>
(
lastVar
,
size
,
virtSymbol
)
);
addQuad
<
QAlloc
>
(
lastVar
,
size
,
virtSymbol
);
}
/// statements
...
...
@@ -321,35 +321,53 @@ void Compiler::visitInit(Init *p) {
auto
info
=
p
->
pident_
->
var
.
lock
();
assert
(
info
);
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
)
{
auto
dest
=
evalExpr
(
p
->
expr_1
);
quads
.
emplace_back
(
make_shared
<
QAssign
>
(
dest
,
Op
::
Copy
,
evalExpr
(
p
->
expr_2
))
);
auto
val
=
evalExpr
(
p
->
expr_2
);
assign
(
p
->
expr_1
,
val
);
}
void
Compiler
::
visitIncr
(
Incr
*
p
)
{
auto
dest
=
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
)
{
auto
dest
=
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
)
{
auto
var
=
evalExpr
(
p
->
expr_
);
endBasicBlock
();
quads
.
emplace_back
(
make_shared
<
QReturn
>
(
var
)
);
addQuad
<
QReturn
>
(
var
);
}
void
Compiler
::
visitVRet
(
VRet
*
p
)
{
endBasicBlock
();
quads
.
emplace_back
(
make_shared
<
QReturn
>
(
nullptr
)
);
addQuad
<
QReturn
>
(
nullptr
);
}
void
Compiler
::
visitCond
(
Cond
*
p
)
{
...
...
@@ -357,11 +375,11 @@ void Compiler::visitCond(Cond *p) {
auto
after
=
make_shared
<
QLabel
>
(
"end_if"
);
endBasicBlock
();
// possible jump -> after
quads
.
emplace_back
(
make_shared
<
QJumpCond
>
(
after
,
Op
::
Not
,
var
)
);
addQuad
<
QJumpCond
>
(
after
,
Op
::
Not
,
var
);
p
->
stmt_
->
accept
(
this
);
endBasicBlock
();
// possible jump <- cond
quads
.
emplace_back
(
after
);
addQuad
(
after
);
}
void
Compiler
::
visitCondElse
(
CondElse
*
p
)
{
...
...
@@ -371,36 +389,36 @@ void Compiler::visitCondElse(CondElse *p) {
auto
var
=
evalExpr
(
p
->
expr_
);
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
);
endBasicBlock
();
// jump -> after
quads
.
emplace_back
(
make_shared
<
QJump
>
(
after
)
);
addQuad
<
QJump
>
(
after
);
quads
.
emplace_back
(
elseBranch
);
addQuad
(
elseBranch
);
p
->
stmt_2
->
accept
(
this
);
endBasicBlock
();
// jump <- cond
quads
.
emplace_back
(
after
);
addQuad
(
after
);
}
void
Compiler
::
visitWhile
(
While
*
p
)
{
auto
cond
=
make_shared
<
QLabel
>
(
"cond"
);
endBasicBlock
();
// jump <- loop -> cond
quads
.
emplace_back
(
make_shared
<
QJump
>
(
cond
)
);
addQuad
<
QJump
>
(
cond
);
// jump <- loop
auto
loop
=
make_shared
<
QLabel
>
(
"loop"
);
quads
.
emplace_back
(
loop
);
addQuad
(
loop
);
p
->
stmt_
->
accept
(
this
);
endBasicBlock
();
// jump <- cond
quads
.
emplace_back
(
cond
);
addQuad
(
cond
);
auto
var
=
evalExpr
(
p
->
expr_
);
endBasicBlock
();
// jump -> loop
quads
.
emplace_back
(
make_shared
<
QJumpCond
>
(
loop
,
Op
::
Copy
,
var
)
);
addQuad
<
QJumpCond
>
(
loop
,
Op
::
Copy
,
var
);
}
void
Compiler
::
visitSExp
(
SExp
*
p
)
{
...
...
src/Compiler.h
View file @
9b245472
...
...
@@ -31,11 +31,22 @@ private:
Quadruple
::
Op
op
;
VariablePtr
lastVar
;
int
lineno
;
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
)
{
if
(
!
expr
)
throw
runtime_error
(
"No expr to eval"
);
lineno
=
expr
->
lineno
;
lastVar
=
nullptr
;
try
{
expr
->
accept
(
this
);
...
...
@@ -60,7 +71,7 @@ private:
};
VariablePtr
alloc
(
VarInfoPtr
info
)
{
if
(
info
->
loc
)
{
if
(
info
->
loc
&&
!
info
->
isInstanceVariable
()
)
{
return
info
->
loc
;
}
auto
v
=
make_shared
<
Variable
>
(
info
);
...
...
@@ -74,8 +85,23 @@ private:
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
assign
(
Expr
*
lval
,
VariablePtr
val
);
void
visitEVar
(
EVar
*
p
)
override
;
void
visitEIndexAcc
(
EIndexAcc
*
p
)
override
;
void
visitEClsMmbr
(
EClsMmbr
*
p
)
override
;
...
...
src/Info.h
View file @
9b245472
...
...
@@ -26,7 +26,8 @@ public:
string
name
;
TypePtr
type
;
int
lineLocation
;
size_t
offset
;
size_t
offset
=
0
;
bool
isInstanceVariable
()
const
{
return
offset
;
};
VariablePtr
loc
;
...
...
src/TypeCheck.cpp
View file @
9b245472
...
...
@@ -117,7 +117,7 @@ void TypeCheck::visitClassFld(ClassFld *decl)
void
TypeCheck
::
visitBlk
(
Blk
*
blk
)
{
BindingPtr
binding
=
blk
->
binding
/*.lock()*/
;
BindingPtr
binding
=
blk
->
getBinding
()
;
if
(
!
binding
)
{
binding
=
make_shared
<
Binding
>
(
scope
->
currentBinding
);
blk
->
binding
=
binding
;
...
...
@@ -310,8 +310,9 @@ void TypeCheck::visitEClsMmbr(EClsMmbr *e_cls_mmbr)
if
(
!
type
)
{
// it is an array and we ask for length
if
(
dynamic_pointer_cast
<
Array
>
(
exprType
))
{
if
(
e_cls_mmbr
->
pident_
->
string_
==
"length"
)
{
lastType
=
make_shared
<
Int
>
();
if
(
e_cls_mmbr
->
pident_
->
string_
==
arrayLengthVar
->
name
)
{
e_cls_mmbr
->
pident_
->
var
=
arrayLengthVar
;
lastType
=
arrayLengthVar
->
type
;
return
;
}
}
...
...
@@ -558,6 +559,8 @@ void TypeCheck::setupEnv() {
scope
->
functions
<<
error
;
}
arrayLengthVar
=
make_shared
<
VarInfo
>
(
"length"
,
make_shared
<
Int
>
());
}
void
TypeCheck
::
check
(
Visitable
*
v
)
...
...
src/TypeCheck.h
View file @
9b245472
...
...
@@ -22,6 +22,8 @@ class TypeCheck : public Visitor
vector
<
pair
<
ClassInfoPtr
,
ClassDef
*>>
classDefs
;
VarInfoPtr
arrayLengthVar
;
void
checkFunction
(
FunctionInfoPtr
f
);
void
checkReturnStatement
(
shared_ptr
<
Type
>
type
,
Stmt
*
stmt
);
void
checkFunctionRet
();
...
...
src/codeGen/Quadruple.h
View file @
9b245472
...
...
@@ -38,8 +38,10 @@ public:
}
};
int
lineno
;
virtual
~
Quadruple
()
{};
virtual
std
::
string
toString
()
const
=
0
;
virtual
std
::
string
toString
()
const
{
return
to_string
(
lineno
)
+
"
\t
"
;
}
;
};
class
QWriteVar
:
public
Quadruple
{
...
...
@@ -47,13 +49,13 @@ public:
VariablePtr
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
{
public:
string
label
;
std
::
string
toString
()
const
override
{
return
"
\"
"
+
label
+
"
\"
:"
;
}
std
::
string
toString
()
const
override
{
return
Quadruple
::
toString
()
+
"
\"
"
+
label
+
"
\"
:"
;
}
QLabel
(
std
::
string
comment
)
:
label
(
comment
)
{}
};
...
...
@@ -80,7 +82,7 @@ public:
explicit
QJump
(
shared_ptr
<
QLabel
>
target
)
:
target
(
std
::
move
(
target
))
{};
std
::
string
toString
()
const
override
{
return
"
\t
jump "
+
target
->
label
;
return
Quadruple
::
toString
()
+
"
jump "
+
target
->
label
;
}
};
...
...
@@ -97,9 +99,9 @@ public:
std
::
string
toString
()
const
override
{
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
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:
std
::
string
toString
()
const
override
{
if
(
num
==
0
)
{
return
"
\t
param self "
+
param
->
name
;
return
Quadruple
::
toString
()
+
"
\t
param self "
+
param
->
name
;
}
else
{
return
"
\t
param #"
+
to_string
(
num
)
+
" <- "
+
param
->
name
;
return
Quadruple
::
toString
()
+
"
\t
param #"
+
to_string
(
num
)
+
" <- "
+
param
->
name
;
}
}
};
...
...
@@ -143,9 +145,9 @@ public:
std
::
string
toString
()
const
override
{
if
(
ret
)
{
return
"
\t
return "
+
ret
->
name
;
return
Quadruple
::
toString
()
+
"
\t
return "
+
ret
->
name
;
}
else
{
return
"
\t
return"
;
return
Quadruple
::
toString
()
+
"
\t
return"
;
}
}
};
...
...
@@ -153,23 +155,31 @@ public:
class
QAccess
:
public
QWriteVar
{
public:
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 (%edx,%eax,2), %eax # Arithmetic: multiply eax by 2 and add edx
VariablePtr
base
;
VariablePtr
index
;
int
multiplier
;
int
offset
;
VariableLocation
access
;
bool
lea
=
false
;
std
::
string
toString
()
const
override
{
auto
ret
=
QWriteVar
::
toString
()
+
"["
+
base
->
name
;
if
(
multiplier
||
!
(
index
->
constExpr
||
!
index
->
val
))
ret
+=
" + "
+
to_string
(
multiplier
)
+
"*"
+
index
->
name
;
if
(
offset
)
ret
+=
" + "
+
to_string
(
offset
);
return
ret
+
"]"
;
auto
ret
=
QWriteVar
::
toString
();
if
(
lea
)
ret
+=
"&"
;
return
ret
+
access
.
toString
();
}
};
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
{
public:
size_t
size
;
...
...
src/codeGen/Variable.h
View file @
9b245472
...
...
@@ -27,4 +27,23 @@ public:
// 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
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