From f30cf42c4b73d50b79c7fe1e3829313839c7ecc8 Mon Sep 17 00:00:00 2001 From: Guy C Date: Tue, 25 Feb 2025 00:05:10 +0000 Subject: [PATCH] style: improve code formatting and consistency in typeChecker and assemblyIR --- src/main/wacc/backend/asmGenerator.scala | 247 ++++++++++++----------- src/main/wacc/backend/assemblyIR.scala | 30 ++- src/main/wacc/frontend/typeChecker.scala | 8 +- 3 files changed, 147 insertions(+), 138 deletions(-) diff --git a/src/main/wacc/backend/asmGenerator.scala b/src/main/wacc/backend/asmGenerator.scala index 1c3a2a9..8d5e746 100644 --- a/src/main/wacc/backend/asmGenerator.scala +++ b/src/main/wacc/backend/asmGenerator.scala @@ -19,7 +19,7 @@ object asmGenerator { val RBP = Register(RegSize.R64, RegName.BP) val RSI = Register(RegSize.R64, RegName.SI) - val _8_BIT_MASK = 0xFF + val _8_BIT_MASK = 0xff object labelGenerator { var labelVal = -1 @@ -27,8 +27,8 @@ object asmGenerator { labelVal += 1 s".L$labelVal" } - def getLabel(target: CallTarget): String = target match{ - case Ident(v,_) => s"wacc_$v" + def getLabel(target: CallTarget): String = target match { + case Ident(v, _) => s"wacc_$v" case Builtin(name) => s"_$name" } } @@ -61,33 +61,31 @@ object asmGenerator { strings: ListBuffer[String] ): List[AsmLine] = { LabelDef(labelName) :: - funcPrologue() ++ + funcPrologue() ++ funcBody ++ - funcEpilogue() + funcEpilogue() } def generateBuiltInFuncs()(using stack: LinkedHashMap[Ident, Int], strings: ListBuffer[String] ): List[AsmLine] = { - wrapFunc(labelGenerator.getLabel(Builtin.Exit), + wrapFunc( + labelGenerator.getLabel(Builtin.Exit), alignStack() ++ - List(Pop(RDI), - assemblyIR.Call(CLibFunc.Exit)) + List(Pop(RDI), assemblyIR.Call(CLibFunc.Exit)) ) ++ - wrapFunc(labelGenerator.getLabel(Builtin.Printf), - alignStack() ++ - List(assemblyIR.Call(CLibFunc.PrintF), - Move(RDI, ImmediateVal(0)), - assemblyIR.Call(CLibFunc.Fflush) - ) - )++ - wrapFunc(labelGenerator.getLabel(Builtin.Malloc), - List() - )++ - wrapFunc(labelGenerator.getLabel(Builtin.Free), - List() - ) + wrapFunc( + labelGenerator.getLabel(Builtin.Printf), + alignStack() ++ + List( + assemblyIR.Call(CLibFunc.PrintF), + Move(RDI, ImmediateVal(0)), + assemblyIR.Call(CLibFunc.Fflush) + ) + ) ++ + wrapFunc(labelGenerator.getLabel(Builtin.Malloc), List()) ++ + wrapFunc(labelGenerator.getLabel(Builtin.Free), List()) } def generateStmt( @@ -95,7 +93,7 @@ object asmGenerator { )(using stack: LinkedHashMap[Ident, Int], strings: ListBuffer[String]): List[AsmLine] = stmt match { case microWacc.Call(Builtin.Exit, code :: _) => - List() + List() case Assign(lhs, rhs) => var dest: IndexAddress = IndexAddress(RSP, 0) // gets overrwitten @@ -188,97 +186,100 @@ object asmGenerator { // TODO other array types case _ => List() } - case BoolLiter(v) => List(Push(ImmediateVal(if (v) 1 else 0))) - case NullLiter() => List(Push(ImmediateVal(0))) + case BoolLiter(v) => List(Push(ImmediateVal(if (v) 1 else 0))) + case NullLiter() => List(Push(ImmediateVal(0))) case ArrayElem(value, indices) => List() - case UnaryOp(x, op) => op match { - // TODO: chr and ord are TYPE CASTS. They do not change the internal value, - // but will need bound checking e.t.c. - case UnaryOperator.Chr => List() - case UnaryOperator.Ord => List() - case UnaryOperator.Len => List() - case UnaryOperator.Negate => List( - Negate(MemLocation(RSP,SizeDir.Word)) - ) - case UnaryOperator.Not => - evalExprOntoStack(x) ++ - List( - Xor(MemLocation(RSP, SizeDir.Word), ImmediateVal(1)) - ) - - } - case BinaryOp(x, y, op) => op match { - case BinaryOperator.Add => - evalExprOntoStack(x) ++ - evalExprOntoStack(y) ++ - List( - Pop(EAX), - Add(MemLocation(RSP, SizeDir.Word), EAX) - // TODO OVERFLOWING - ) - case BinaryOperator.Sub => - evalExprOntoStack(x) ++ - evalExprOntoStack(y) ++ - List( - Pop(EAX), - Subtract(MemLocation(RSP, SizeDir.Word), EAX) - // TODO OVERFLOWING - ) - case BinaryOperator.Mul => - evalExprOntoStack(x) ++ - evalExprOntoStack(y) ++ - List( - Pop(EAX), - Multiply(MemLocation(RSP, SizeDir.Word), EAX) - // TODO OVERFLOWING - ) - case BinaryOperator.Div => - evalExprOntoStack(y) ++ - evalExprOntoStack(x) ++ - List( - Pop(EAX), - Divide(MemLocation(RSP, SizeDir.Word)), - Add(RSP, ImmediateVal(8)), - Push(EAX) - // TODO CHECK DIVISOR IS NOT 0 - ) - case BinaryOperator.Mod => - evalExprOntoStack(y) ++ - evalExprOntoStack(x) ++ - List( - Pop(EAX), - Divide(MemLocation(RSP, SizeDir.Word)), - Add(RSP, ImmediateVal(8)), - Push(EDX) - // TODO CHECK DIVISOR IS NOT 0 + case UnaryOp(x, op) => + op match { + // TODO: chr and ord are TYPE CASTS. They do not change the internal value, + // but will need bound checking e.t.c. + case UnaryOperator.Chr => List() + case UnaryOperator.Ord => List() + case UnaryOperator.Len => List() + case UnaryOperator.Negate => + List( + Negate(MemLocation(RSP, SizeDir.Word)) ) - case BinaryOperator.Eq => - generateComparison(x, y, Cond.Equal) - case BinaryOperator.Neq => - generateComparison(x, y, Cond.NotEqual) - case BinaryOperator.Greater => - generateComparison(x, y, Cond.Greater) - case BinaryOperator.GreaterEq => - generateComparison(x, y, Cond.GreaterEqual) - case BinaryOperator.Less => - generateComparison(x, y, Cond.Less) - case BinaryOperator.LessEq => - generateComparison(x, y, Cond.LessEqual) - case BinaryOperator.And => - evalExprOntoStack(x) ++ - evalExprOntoStack(y) ++ - List( - Pop(EAX), - And(MemLocation(RSP, SizeDir.Word), EAX), - ) - case BinaryOperator.Or => - evalExprOntoStack(x) ++ - evalExprOntoStack(y) ++ - List( - Pop(EAX), - Or(MemLocation(RSP, SizeDir.Word), EAX), - ) - } + case UnaryOperator.Not => + evalExprOntoStack(x) ++ + List( + Xor(MemLocation(RSP, SizeDir.Word), ImmediateVal(1)) + ) + + } + case BinaryOp(x, y, op) => + op match { + case BinaryOperator.Add => + evalExprOntoStack(x) ++ + evalExprOntoStack(y) ++ + List( + Pop(EAX), + Add(MemLocation(RSP, SizeDir.Word), EAX) + // TODO OVERFLOWING + ) + case BinaryOperator.Sub => + evalExprOntoStack(x) ++ + evalExprOntoStack(y) ++ + List( + Pop(EAX), + Subtract(MemLocation(RSP, SizeDir.Word), EAX) + // TODO OVERFLOWING + ) + case BinaryOperator.Mul => + evalExprOntoStack(x) ++ + evalExprOntoStack(y) ++ + List( + Pop(EAX), + Multiply(MemLocation(RSP, SizeDir.Word), EAX) + // TODO OVERFLOWING + ) + case BinaryOperator.Div => + evalExprOntoStack(y) ++ + evalExprOntoStack(x) ++ + List( + Pop(EAX), + Divide(MemLocation(RSP, SizeDir.Word)), + Add(RSP, ImmediateVal(8)), + Push(EAX) + // TODO CHECK DIVISOR IS NOT 0 + ) + case BinaryOperator.Mod => + evalExprOntoStack(y) ++ + evalExprOntoStack(x) ++ + List( + Pop(EAX), + Divide(MemLocation(RSP, SizeDir.Word)), + Add(RSP, ImmediateVal(8)), + Push(EDX) + // TODO CHECK DIVISOR IS NOT 0 + ) + case BinaryOperator.Eq => + generateComparison(x, y, Cond.Equal) + case BinaryOperator.Neq => + generateComparison(x, y, Cond.NotEqual) + case BinaryOperator.Greater => + generateComparison(x, y, Cond.Greater) + case BinaryOperator.GreaterEq => + generateComparison(x, y, Cond.GreaterEqual) + case BinaryOperator.Less => + generateComparison(x, y, Cond.Less) + case BinaryOperator.LessEq => + generateComparison(x, y, Cond.LessEqual) + case BinaryOperator.And => + evalExprOntoStack(x) ++ + evalExprOntoStack(y) ++ + List( + Pop(EAX), + And(MemLocation(RSP, SizeDir.Word), EAX) + ) + case BinaryOperator.Or => + evalExprOntoStack(x) ++ + evalExprOntoStack(y) ++ + List( + Pop(EAX), + Or(MemLocation(RSP, SizeDir.Word), EAX) + ) + } case microWacc.Call(target, args) => List() } } @@ -308,19 +309,19 @@ object asmGenerator { // } - def generateComparison(x : Expr, y: Expr, cond: Cond)(using + def generateComparison(x: Expr, y: Expr, cond: Cond)(using stack: LinkedHashMap[Ident, Int], strings: ListBuffer[String] ): List[AsmLine] = { - evalExprOntoStack(x) ++ - evalExprOntoStack(y) ++ - List( - Pop(EAX), - Compare(MemLocation(RSP, SizeDir.Word), EAX), - Set(Register(RegSize.Byte, RegName.AL), cond), - And(EAX, ImmediateVal(_8_BIT_MASK)), - Push(EAX) - ) + evalExprOntoStack(x) ++ + evalExprOntoStack(y) ++ + List( + Pop(EAX), + Compare(MemLocation(RSP, SizeDir.Word), EAX), + Set(Register(RegSize.Byte, RegName.AL), cond), + And(EAX, ImmediateVal(_8_BIT_MASK)), + Push(EAX) + ) } def accessVar(ident: Ident)(using stack: LinkedHashMap[Ident, Int]): IndexAddress = IndexAddress(RSP, (stack.size - stack(ident)) * 8) @@ -397,8 +398,8 @@ object asmGenerator { ) } else { - evalExprOntoStack(expr) ++ - List(Pop(RSI)) + evalExprOntoStack(expr) ++ + List(Pop(RSI)) }) // print the value ++ diff --git a/src/main/wacc/backend/assemblyIR.scala b/src/main/wacc/backend/assemblyIR.scala index 22ca36b..14e4f4f 100644 --- a/src/main/wacc/backend/assemblyIR.scala +++ b/src/main/wacc/backend/assemblyIR.scala @@ -12,14 +12,15 @@ object assemblyIR { case Byte override def toString = this match { - case R64 => "r" - case E32 => "e" + case R64 => "r" + case E32 => "e" case Byte => "" } } enum RegName { - case AX, AL, BX, CX, DX, SI, DI, SP, BP, IP, Reg8, Reg9, Reg10, Reg11, Reg12, Reg13, Reg14, Reg15 + case AX, AL, BX, CX, DX, SI, DI, SP, BP, IP, Reg8, Reg9, Reg10, Reg11, Reg12, Reg13, Reg14, + Reg15 override def toString = this match { case AX => "ax" case AL => "al" @@ -59,17 +60,24 @@ object assemblyIR { } } - //TODO register naming conventions are wrong + // TODO register naming conventions are wrong case class Register(size: RegSize, name: RegName) extends Dest with Src { override def toString = s"${size}${name}" } - case class MemLocation(pointer: Long | Register, opSize: SizeDir = SizeDir.Unspecified) extends Dest with Src { + case class MemLocation(pointer: Long | Register, opSize: SizeDir = SizeDir.Unspecified) + extends Dest + with Src { override def toString = pointer match { case hex: Long => opSize.toString + f"[0x$hex%X]" case reg: Register => opSize.toString + s"[$reg]" } } - case class IndexAddress(base: Register, offset: Int | LabelArg, opSize: SizeDir = SizeDir.Unspecified) extends Dest with Src { + case class IndexAddress( + base: Register, + offset: Int | LabelArg, + opSize: SizeDir = SizeDir.Unspecified + ) extends Dest + with Src { override def toString = s"$opSize[$base + $offset]" } @@ -111,7 +119,7 @@ object assemblyIR { extends Operation(s"j${condition.toString}", op1) case class Set(op1: Dest, condition: Cond = Cond.Always) - extends Operation(s"set${condition.toString}", op1) + extends Operation(s"set${condition.toString}", op1) case class LabelDef(name: String) extends AsmLine { override def toString = s"$name:" @@ -165,14 +173,14 @@ object assemblyIR { } enum SizeDir { - case Byte, Word, Unspecified + case Byte, Word, Unspecified private val ptr = "ptr " override def toString(): String = this match { - case Byte => "byte " + ptr - case Word => "word " + ptr + case Byte => "byte " + ptr + case Word => "word " + ptr case Unspecified => "" } } -} \ No newline at end of file +} diff --git a/src/main/wacc/frontend/typeChecker.scala b/src/main/wacc/frontend/typeChecker.scala index b854272..c3f2ba8 100644 --- a/src/main/wacc/frontend/typeChecker.scala +++ b/src/main/wacc/frontend/typeChecker.scala @@ -180,7 +180,7 @@ object typeChecker { microWacc.Builtin.Read, List( destTy match { - case KnownType.Int => "%d".toMicroWaccCharArray + case KnownType.Int => "%d".toMicroWaccCharArray case KnownType.Char | _ => "%c".toMicroWaccCharArray }, destTyped @@ -218,9 +218,9 @@ object typeChecker { val exprTyped = checkValue(expr, Constraint.Unconstrained) val format = exprTyped.ty match { case KnownType.Bool | KnownType.String => "%s" - case KnownType.Char => "%c" - case KnownType.Int => "%d" - case _ => "%p" + case KnownType.Char => "%c" + case KnownType.Int => "%d" + case _ => "%p" } List( microWacc.Call(