completed
This commit is contained in:
@@ -199,6 +199,8 @@ abstract class X86Compiler extends BugReporter with Codegen {
|
||||
* TODO: Fill in transUn with the appropriate code.
|
||||
*/
|
||||
def transUn(op: String)(sp: Loc) = op match {
|
||||
case "-" => emitln(s"neg ${regs(sp)}")
|
||||
case "+" => ()
|
||||
case _ => BUG(s"Unary operator $op undefined")
|
||||
}
|
||||
|
||||
@@ -224,6 +226,7 @@ abstract class X86Compiler extends BugReporter with Codegen {
|
||||
var nLabel = 0
|
||||
def freshLabel(pref: String) = { nLabel += 1; s"$pref$nLabel" }
|
||||
|
||||
|
||||
/*
|
||||
* Generate code that jumps to the label 'label'
|
||||
* if the CPU flags are verifying the operator
|
||||
@@ -260,18 +263,48 @@ abstract class X86Compiler extends BugReporter with Codegen {
|
||||
def trans(exp: Exp, sp: Loc)(env: LocationEnv): Unit = exp match {
|
||||
case Lit(x) =>
|
||||
emitln(s"movq $$$x, ${regs(sp)}")
|
||||
case Unary(op, v) => ()
|
||||
case Prim(op, lop, rop) => ()
|
||||
case Let(x, a, b) => ()
|
||||
case Ref(x) => ()
|
||||
case Cond(op, l, r) => ()
|
||||
case If(cond, tBranch, eBranch) => ()
|
||||
case VarDec(x, rhs, body) => ()
|
||||
case VarAssign(x, rhs) => ()
|
||||
case Unary(op, v) =>
|
||||
trans(v, sp)(env)
|
||||
transUn(op)(sp)
|
||||
case Prim(op, lop, rop) =>
|
||||
trans(lop, sp)(env)
|
||||
trans(rop, sp + 1)(env)
|
||||
transBin(op)(sp, sp + 1)
|
||||
case Let(x, a, b) =>
|
||||
trans(a, sp)(env)
|
||||
trans(b, sp + 1)(env.withVal(x, sp))
|
||||
emitln(s"movq ${regs(sp + 1)}, ${regs(sp)}")
|
||||
case Ref(x) =>
|
||||
emitln(s"movq ${regs(env.apply(x))}, ${regs(sp)}")
|
||||
case Cond(op, l, r) =>
|
||||
trans(l, sp)(env)
|
||||
trans(r, sp + 1)(env)
|
||||
emitln(s"cmpq ${regs(sp + 1)}, ${regs(sp)}")
|
||||
case If(cond, tBranch, eBranch) =>
|
||||
trans(cond, sp)(env)
|
||||
val lab = freshLabel("if")
|
||||
transJumpIf(cond.op)(lab)
|
||||
trans(eBranch, sp)(env)
|
||||
emitln(s"jmp ${lab}_skip")
|
||||
emitln(s"${lab}:", 0)
|
||||
trans(tBranch, sp)(env)
|
||||
emitln(s"${lab}_skip:", 0)
|
||||
case VarDec(x, rhs, body) =>
|
||||
trans(rhs, sp)(env)
|
||||
trans(body, sp + 1)(env.withVal(x, sp))
|
||||
emitln(s"movq ${regs(sp + 1)}, ${regs(sp)}")
|
||||
case VarAssign(x, rhs) =>
|
||||
trans(rhs, sp)(env)
|
||||
emitln(s"movq ${regs(sp)}, ${regs(env.apply(x))}")
|
||||
case While(cond, lBody, body) =>
|
||||
val lab = freshLabel("loop")
|
||||
emitln(s"jmp ${lab}_cond")
|
||||
emitln(s"${lab}_body:", 0)
|
||||
() // TODO: continue ...
|
||||
trans(lBody, sp)(env)
|
||||
emitln(s"${lab}_cond:", 0)
|
||||
trans(cond, sp)(env)
|
||||
transJumpIf(cond.op)(s"${lab}_body")
|
||||
trans(body, sp)(env)
|
||||
// TODO: continue ... Done
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,6 +190,8 @@ class StackInterpreter extends Interpreter with BugReporter {
|
||||
* TODO: Implement the appropriate code as defined in the handout.
|
||||
*/
|
||||
def evalUn(op: String)(sp: Loc) = op match {
|
||||
case "+" => memory(sp)
|
||||
case "-" => -memory(sp)
|
||||
case _ => BUG(s"Unary operator $op undefined")
|
||||
}
|
||||
|
||||
@@ -218,6 +220,11 @@ class StackInterpreter extends Interpreter with BugReporter {
|
||||
def evalCond(op: String)(sp: Loc, sp1: Loc) = {
|
||||
flag = op match {
|
||||
case "==" => memory(sp) == memory(sp1)
|
||||
case "!=" => memory(sp) != memory(sp1)
|
||||
case ">=" => memory(sp) >= memory(sp1)
|
||||
case "<=" => memory(sp) <= memory(sp1)
|
||||
case ">" => memory(sp) > memory(sp1)
|
||||
case "<" => memory(sp) < memory(sp1)
|
||||
case _ => BUG(s"Binary operator $op undefined")
|
||||
}
|
||||
}
|
||||
@@ -249,14 +256,32 @@ class StackInterpreter extends Interpreter with BugReporter {
|
||||
def eval(exp: Exp, sp: Loc)(env: LocationEnv): Unit = exp match {
|
||||
case Lit(x) =>
|
||||
memory(sp) = x
|
||||
case Unary(op, v) => ???
|
||||
case Prim(op, lop, rop) => ???
|
||||
case Let(x, a, b) => ???
|
||||
case Ref(x) => ???
|
||||
case Cond(op, l, r) => ???
|
||||
case If(cond, tBranch, eBranch) => ???
|
||||
case VarDec(x, rhs, body) => ???
|
||||
case VarAssign(x, rhs) => ???
|
||||
case Unary(op, v) =>
|
||||
eval(v, sp)(env)
|
||||
evalUn(op)(sp)
|
||||
case Prim(op, lop, rop) =>
|
||||
eval(a, sp)(env)
|
||||
eval(b, sp + 1)(env)
|
||||
evalBin(sp, sp + 1)
|
||||
case Let(x, a, b) =>
|
||||
eval(a, sp)(env)
|
||||
eval(b, sp + 1)(env.withVal(x, sp))
|
||||
memory(sp) = memory(sp + 1)
|
||||
case Ref(x) =>
|
||||
memory(sp) = memory(env.apply(x))
|
||||
case Cond(op, l, r) =>
|
||||
eval(l, sp)(env)
|
||||
eval(r, sp + 1)(env)
|
||||
evalCond(op)(sp, sp + 1)
|
||||
case If(cond, tBranch, eBranch) =>
|
||||
eval(cond, sp)(env)
|
||||
eval(if(flag)tBranch else eBranch, sp)
|
||||
case VarDec(x, rhs, body) =>
|
||||
eval(rhs, sp)(env)
|
||||
eval(body, sp + 1)(env.withVal(x, sp))
|
||||
case VarAssign(x, rhs) =>
|
||||
eval(rhs, sp)(env)
|
||||
memory(env.apply(x)) = memory(sp)
|
||||
case While(cond, lbody, body) =>
|
||||
eval(cond, sp)(env)
|
||||
while (flag) {
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package project2
|
||||
|
||||
import java.awt.RenderingHints.Key
|
||||
|
||||
// Class used to carry position information within the source code
|
||||
case class Position(gapLine: Int, gapCol: Int, startLine: Int, startCol: Int, endLine: Int, endCol: Int)
|
||||
|
||||
@@ -426,7 +428,11 @@ class ArithParser(in: Scanner) extends Parser(in) {
|
||||
def parseExpression: Exp = parseExpression(0)
|
||||
def parseExpression(min: Int): Exp = {
|
||||
var res = parseUAtom
|
||||
// TODO: complete
|
||||
// TODO: complete DONE?
|
||||
if (in.hasNext(isOperator)) {
|
||||
val (op, pos) = getOperator
|
||||
Prim(op, res, parseUAtom).withPos(pos)
|
||||
}
|
||||
res
|
||||
}
|
||||
}
|
||||
@@ -469,7 +475,7 @@ class LetParser(in: Scanner) extends ArithParser(in) {
|
||||
case Ident(x) =>
|
||||
val (_, pos) = getName
|
||||
Ref(x).withPos(pos)
|
||||
// TODO: remove ??? and add the implementation for this case
|
||||
// TODO: remove ??? and add the implementation for this case DONE
|
||||
case _ => abort(s"Illegal start of simple expression")
|
||||
}
|
||||
|
||||
@@ -532,7 +538,20 @@ class BranchParser(in: Scanner) extends LetParser(in) {
|
||||
}
|
||||
|
||||
// TODO: remove ??? and complete the implementation.
|
||||
override def parseSimpleExpression = ???
|
||||
override def parseSimpleExpression: Exp = in.peek match {
|
||||
case Keyword("if") =>
|
||||
val pos = in.next().pos
|
||||
accept('(')
|
||||
val cond = parseCondition
|
||||
accept(')')
|
||||
val if_stmt = parseSimpleExpression
|
||||
if (in.hasNext(_ == Keyword("else"))) {
|
||||
val else_stmt = parseSimpleExpression
|
||||
If(cond, if_stmt, else_stmt).withPos(pos)
|
||||
}
|
||||
else expected("missing else statement")
|
||||
case _ => super.parseSimpleExpression
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -562,12 +581,24 @@ class VariableParser(in: Scanner) extends BranchParser(in) {
|
||||
|
||||
// TODO: remove ??? and complete the implementation.
|
||||
override def parseExpression = in.peek match {
|
||||
case _ => ???
|
||||
case Keyword("val") => super.parseExpression
|
||||
case Keyword("var") =>
|
||||
in.next()
|
||||
val (name, pos) = getName
|
||||
accept('=')
|
||||
val rhs = parseSimpleExpression
|
||||
accept(';')
|
||||
val body = parseExpression
|
||||
Var(name, rhs, body).withPos(pos)
|
||||
case _ => parseSimpleExpression
|
||||
}
|
||||
|
||||
// TODO: remove ??? and complete the implementation.
|
||||
override def parseSimpleExpression = (in.peek, in.peek1) match {
|
||||
case _ => ???
|
||||
case (Ident(x), Delim('=')) =>
|
||||
val pos = in.pos
|
||||
VarAssign(x, parseSimpleExpression).withPos(pos)
|
||||
case _ => super.parseExpression
|
||||
}
|
||||
}
|
||||
|
||||
@@ -597,5 +628,16 @@ class LoopParser(in: Scanner) extends VariableParser(in) {
|
||||
import Tokens._
|
||||
|
||||
// TODO: remove ??? and complete the implementation.
|
||||
override def parseExpression = ???
|
||||
override def parseExpression = in.peek match {
|
||||
case Keyword("while") =>
|
||||
val pos = in.next().pos
|
||||
accept('(')
|
||||
val cond = parseCondition
|
||||
accept(')')
|
||||
val simp = parseSimpleExpression
|
||||
val body = parseExpression
|
||||
While(cond, simp, body).withPos(pos)
|
||||
case _ =>
|
||||
super.parseExpression
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,33 +124,43 @@ class SemanticAnalyzer(parser: Parser) extends Reporter {
|
||||
error("undefined primitive operator")
|
||||
analyze(lop)
|
||||
analyze(rop)
|
||||
case Let(x, a, b) =>
|
||||
case Let(x, a, b) => // val x = a; b
|
||||
// Done: check variable reuse
|
||||
if(!(env.vars.contains(x) && env.vars[x]))
|
||||
if(!env.vars.contains(x))
|
||||
error(s"cannot assign variable $x")
|
||||
analyze(a)(env)
|
||||
analyze(b)(env.withVal(x))
|
||||
case Ref(x) =>
|
||||
if (!env.vars.contains(x))
|
||||
error(s"symbol $x not found")
|
||||
()// Done
|
||||
error(s"symbol $x not defined")
|
||||
// Done
|
||||
case Cond(op, l, r) =>
|
||||
// if (!isBOperator(op))
|
||||
// error(s"$op is not a boolean operator")
|
||||
if (!isBOperator(op))
|
||||
error(s"$op is not a boolean operator")
|
||||
analyze(op)
|
||||
analyze(l)
|
||||
analyze(r)
|
||||
() // Done
|
||||
// Done
|
||||
case If(cond, tBranch, eBranch) =>
|
||||
analyze(cond)(env)
|
||||
analyze(tBranch)(env)
|
||||
analyze(eBranch)(env)
|
||||
case VarDec(x, rhs, body) =>
|
||||
() // TODO
|
||||
case VarAssign(x, rhs) => //diff w/ LET??
|
||||
() // TODO
|
||||
case VarDec(x, rhs, body) => // var x = rhs; body
|
||||
if (env.vars.contains(x))
|
||||
error(s"symbol $x already defined")
|
||||
analyze(rhs)(env)
|
||||
analyze(body)(env)
|
||||
// TODO
|
||||
case VarAssign(x, rhs) => // x = rhs
|
||||
if (!(env.vars.contains(x) && env.vars[x]))
|
||||
error(s"cannot assign $x: ${if(env.vars.contains(x))"immutable"else"undefined"}")
|
||||
analyze(rhs)
|
||||
// TODO
|
||||
case While(cond, lBody, body) =>
|
||||
() // TODO
|
||||
analyze(cond)
|
||||
analyze(lBody)
|
||||
analyze(body)
|
||||
// TODO
|
||||
case _ => abort(s"unknown AST node $exp")
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user