Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Haley Sapphie Owsianko
ACC-project
Commits
e160007d
Commit
e160007d
authored
Mar 24, 2021
by
Sapphie
Browse files
Refactor LetP translation
parent
e9c08c8d
Changes
1
Hide whitespace changes
Inline
Side-by-side
compiler/src/l3/CPSValueRepresenter.scala
View file @
e160007d
...
...
@@ -8,9 +8,7 @@ import l3.{CPSTestPrimitive => CPST}
object
CPSValueRepresenter
extends
(
H
.
Tree
=>
L
.
Tree
)
{
def
apply
(
tree
:
H.Tree
)
:
L.Tree
=
tree
match
{
case
H
.
LetP
(
n
,
prim
,
Seq
(
x
),
body
)
=>
applyLetPUnary
(
n
,
prim
,
x
,
body
)
case
H
.
LetP
(
n
,
prim
,
Seq
(
x
,
y
),
body
)
=>
applyLetPBinary
(
n
,
prim
,
x
,
y
,
body
)
case
H
.
LetP
(
n
,
prim
,
Seq
(
x
,
y
,
z
),
body
)
=>
applyLetPTernary
(
n
,
prim
,
x
,
y
,
z
,
body
)
case
H
.
LetP
(
n
,
prim
,
args
,
body
)
=>
applyLetP
(
n
,
prim
,
args
,
body
)
case
H
.
LetF
(
funs
,
body
)
=>
val
lFuns
=
funs
.
map
(
f
=>
L
.
Fun
(
f
.
name
,
f
.
retC
,
f
.
args
,
apply
(
f
.
body
)))
L
.
LetF
(
lFuns
,
apply
(
body
))
...
...
@@ -62,56 +60,14 @@ object CPSValueRepresenter extends (H.Tree => L.Tree) {
private
def
getMaskR
(
numBits
:
Int
)
:
Either
[
H.Atom
,
L.Atom
]
=
Right
(
L
.
AtomL
((
1
<<
numBits
)
-
1
))
private
def
applyLetP
(
n
:
H.Name
,
prim
:
L3
,
args
:
Seq
[
H.Atom
],
body
:
H.Tree
)
:
L.LetP
=
{
/*
// Only to be used in cases where you can be reasonably sure you're
// dealing with integers
private def lit2Int(l: CL3Literal): Int = {
l match {
case IntLit(i) => i.toInt
case _ => 0
}
}
private def addrConv(x: H.Atom): L.Atom = {
x match {
case H.AtomL(l) => L.AtomL(lit2Int(l))
case H.AtomN(n) => L.AtomN(n)
}
}
// */
// In hindsight, splitting the functions wasn't the cleanest decision
// TODO: refactor
// Transforms value primitives that take a single argument
private
def
applyLetPUnary
(
n
:
H.Name
,
prim
:
L3
,
x
:
H.Atom
,
body
:
H.Tree
)
:
L.LetP
=
{
prim
match
{
case
L3
.
BlockAlloc
(
tag
)
=>
???
case
L3
.
BlockTag
=>
// Unsure how I'm doing this, but in theory, addresses can never be
// literals, therefore we can assume x is a name
L
.
LetP
(
n
,
CPS
.
BlockTag
,
Seq
(
rewrite
(
x
)),
apply
(
body
))
case
L3
.
BlockLength
=>
???
case
L3
.
ByteWrite
=>
???
case
L3
.
CharToInt
=>
L
.
LetP
(
n
,
CPS
.
ShiftRight
,
Seq
(
rewrite
(
x
),
L
.
AtomL
(
2
)),
apply
(
body
))
case
L3
.
Id
=>
L
.
LetP
(
n
,
CPS
.
Id
,
Seq
(
rewrite
(
x
)),
apply
(
body
))
case
L3
.
IntToChar
=>
???
case
_
=>
throw
new
Exception
(
"Unreachable code (unary letP) "
+
prim
.
getClass
)
}
}
// Transforms value primitives that take 2 arguments
private
def
applyLetPBinary
(
n
:
H.Name
,
prim
:
L3
,
x
:
H.Atom
,
y
:
H.Atom
,
body
:
H.Tree
)
:
L.LetP
=
{
val
lAtomOne
:
Either
[
H.Atom
,
L.Atom
]
=
Right
(
L
.
AtomL
(
1
))
// Generates the LetP tree for a brute "untag, apply, retag" operation
def
rawTree
(
op
:
CPS
)
:
L.LetP
=
{
lazy
val
x
=
args
(
0
)
lazy
val
y
=
args
(
1
)
lazy
val
z
=
args
(
2
)
def
rawBinaryTree
(
op
:
CPS
)
:
L.LetP
=
{
// Untag both values
tempLetP
(
CPS
.
ShiftRight
,
Seq
(
Left
(
x
),
lAtomOne
))
{
x1
=>
tempLetP
(
CPS
.
ShiftRight
,
Seq
(
Left
(
y
),
lAtomOne
))
{
y1
=>
...
...
@@ -127,6 +83,7 @@ object CPSValueRepresenter extends (H.Tree => L.Tree) {
}
prim
match
{
case
L3
.
BlockSet
=>
???
case
L3
.
BlockGet
=>
// In theory, x has to be a name, since there cannot be pointer literals
val
block
=
rewrite
(
x
)
...
...
@@ -151,8 +108,8 @@ object CPSValueRepresenter extends (H.Tree => L.Tree) {
}
// I don't think there is a way to do this in a smart way
case
L3
.
IntDiv
=>
rawTree
(
CPS
.
Div
)
case
L3
.
IntMod
=>
rawTree
(
CPS
.
Mod
)
case
L3
.
IntDiv
=>
raw
Binary
Tree
(
CPS
.
Div
)
case
L3
.
IntMod
=>
raw
Binary
Tree
(
CPS
.
Mod
)
case
L3
.
IntShiftLeft
=>
tempLetP
(
CPS
.
Sub
,
Seq
(
Left
(
x
),
lAtomOne
))
{
x1
=>
...
...
@@ -181,17 +138,26 @@ object CPSValueRepresenter extends (H.Tree => L.Tree) {
L
.
LetP
(
n
,
CPS
.
XOr
,
Seq
(
x1
,
rewrite
(
y
)),
apply
(
body
))
}
case
_
=>
throw
new
Exception
(
"Unreachable code (binary letP)"
)
}
}
private
def
applyLetPTernary
(
n
:
H.Name
,
prim
:
L3
,
x
:
H.Atom
,
y
:
H.Atom
,
z
:
H.Atom
,
body
:
H.Tree
)
:
L.LetP
=
{
prim
match
{
case
L3
.
BlockSet
=>
???
case
_
=>
throw
new
Exception
(
"Unreachable code (ternary letP)"
)
case
L3
.
BlockAlloc
(
tag
)
=>
???
case
L3
.
BlockTag
=>
// Unsure how I'm doing this, but in theory, addresses can never be
// literals, therefore we can assume x is a name
L
.
LetP
(
n
,
CPS
.
BlockTag
,
Seq
(
rewrite
(
x
)),
apply
(
body
))
case
L3
.
BlockLength
=>
???
case
L3
.
ByteWrite
=>
???
case
L3
.
CharToInt
=>
L
.
LetP
(
n
,
CPS
.
ShiftRight
,
Seq
(
rewrite
(
x
),
L
.
AtomL
(
2
)),
apply
(
body
))
case
L3
.
Id
=>
L
.
LetP
(
n
,
CPS
.
Id
,
Seq
(
rewrite
(
x
)),
apply
(
body
))
case
L3
.
IntToChar
=>
???
case
_
=>
throw
new
Exception
(
"Unreachable code (unary letP) "
+
prim
.
getClass
)
}
}
// Creates an outer LetP, and binds the result to a name,
// then passes the name to mkBody
// Works similarly to transform in the CL3->CPS translation
...
...
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