feat: almost implemented arrays
This commit is contained in:
@@ -148,9 +148,22 @@ object asmGenerator {
|
||||
)
|
||||
)
|
||||
|
||||
chain ++= wrapBuiltinFunc(
|
||||
labelGenerator.getLabel(Builtin.PrintCharArray),
|
||||
Chain(
|
||||
stack.align(),
|
||||
Load(RDX, IndexAddress(RSI, 8)),
|
||||
Move(RSI, MemLocation(RSI)),
|
||||
assemblyIR.Call(CLibFunc.PrintF),
|
||||
Xor(RDI, RDI),
|
||||
assemblyIR.Call(CLibFunc.Fflush)
|
||||
)
|
||||
)
|
||||
|
||||
chain ++= wrapBuiltinFunc(
|
||||
labelGenerator.getLabel(Builtin.Malloc),
|
||||
Chain.one(stack.align())
|
||||
Chain(stack.align(), assemblyIR.Call(CLibFunc.Malloc))
|
||||
// Out of memory check is optional
|
||||
)
|
||||
|
||||
chain ++= wrapBuiltinFunc(labelGenerator.getLabel(Builtin.Free), Chain.empty)
|
||||
@@ -211,19 +224,25 @@ object asmGenerator {
|
||||
var chain = Chain.empty[AsmLine]
|
||||
stmt match {
|
||||
case Assign(lhs, rhs) =>
|
||||
var dest: () => IndexAddress = () => IndexAddress(RAX, 0) // overwritten below
|
||||
|
||||
lhs match {
|
||||
case ident: Ident =>
|
||||
dest = stack.accessVar(ident)
|
||||
val dest = stack.accessVar(ident)
|
||||
if (!stack.contains(ident)) chain += stack.reserve(ident)
|
||||
// TODO lhs = arrayElem
|
||||
case _ =>
|
||||
}
|
||||
|
||||
chain ++= evalExprOntoStack(rhs)
|
||||
chain += stack.pop(RAX)
|
||||
chain += Move(dest(), RAX)
|
||||
chain ++= evalExprOntoStack(rhs)
|
||||
chain += stack.pop(RDX)
|
||||
chain += Move(dest(), RDX)
|
||||
case ArrayElem(x, i) =>
|
||||
chain ++= evalExprOntoStack(x)
|
||||
chain ++= evalExprOntoStack(i)
|
||||
chain ++= evalExprOntoStack(rhs)
|
||||
chain += stack.pop(RAX)
|
||||
chain += stack.pop(RCX)
|
||||
chain += stack.pop(RDX)
|
||||
|
||||
chain += Move(IndexAddress(RDX, 8, RCX, 8), RAX)
|
||||
}
|
||||
|
||||
case If(cond, thenBranch, elseBranch) =>
|
||||
val elseLabel = labelGenerator.getLabel()
|
||||
@@ -290,19 +309,43 @@ object asmGenerator {
|
||||
strings += elems.collect { case CharLiter(v) => v }.mkString
|
||||
chain += Load(RAX, IndexAddress(RIP, LabelArg(s".L.str${strings.size - 1}")))
|
||||
chain += stack.push(RAX)
|
||||
case _ => // Other array types TODO
|
||||
case _ =>
|
||||
chain ++= generateCall(
|
||||
microWacc.Call(Builtin.Malloc, List(IntLiter((elems.size + 1) * 8))),
|
||||
isTail = false
|
||||
)
|
||||
chain += stack.push(RAX)
|
||||
// Store the length of the array at the start
|
||||
chain += Move(MemLocation(RAX, SizeDir.DWord), ImmediateVal(elems.size))
|
||||
elems.zipWithIndex.foldMap { (elem, i) =>
|
||||
chain ++= evalExprOntoStack(elem)
|
||||
chain += stack.pop(RCX)
|
||||
chain += stack.pop(RAX)
|
||||
chain += Move(IndexAddress(RAX, 8 * (i + 1)), RCX)
|
||||
chain += stack.push(RAX)
|
||||
}
|
||||
}
|
||||
|
||||
case BoolLiter(true) => chain += stack.push(ImmediateVal(1))
|
||||
case BoolLiter(false) =>
|
||||
chain += Xor(RAX, RAX)
|
||||
chain += stack.push(RAX)
|
||||
case NullLiter() => chain += stack.push(ImmediateVal(0))
|
||||
case ArrayElem(_, _) => // TODO: Implement handling
|
||||
case NullLiter() => chain += stack.push(ImmediateVal(0))
|
||||
case ArrayElem(x, i) =>
|
||||
chain ++= evalExprOntoStack(x)
|
||||
chain ++= evalExprOntoStack(i)
|
||||
chain += stack.pop(RCX)
|
||||
chain += stack.pop(RAX)
|
||||
// + 1 because we store the length of the array at the start
|
||||
chain += stack.push(IndexAddress(RAX, 8, RCX, 8))
|
||||
case UnaryOp(x, op) =>
|
||||
chain ++= evalExprOntoStack(x)
|
||||
op match {
|
||||
case UnaryOperator.Chr | UnaryOperator.Ord | UnaryOperator.Len => // No op needed
|
||||
case UnaryOperator.Chr | UnaryOperator.Ord => // No op needed
|
||||
case UnaryOperator.Len =>
|
||||
// Access the elem
|
||||
chain += stack.pop(RAX)
|
||||
chain += Push(MemLocation(RAX))
|
||||
case UnaryOperator.Negate => chain += Negate(stack.head(SizeDir.DWord))
|
||||
case UnaryOperator.Not =>
|
||||
chain += Xor(stack.head(SizeDir.DWord), ImmediateVal(1))
|
||||
|
||||
Reference in New Issue
Block a user