pass all tests

master
Chiyoda Sumika 10 months ago
parent 441add2c71
commit 9562517e28

@ -42,6 +42,9 @@ OPTION: compX86, intStack, intValue (default)""")
args(0) args(0)
} }
// val source = Source.fromFile("examples/unexpected_character.scala")
// val src = try source.getLines mkString "\n" finally source.close()
println("============ SRC CODE ============") println("============ SRC CODE ============")
println(src) println(src)
println("==================================\n") println("==================================\n")
@ -51,7 +54,7 @@ OPTION: compX86, intStack, intValue (default)""")
// Parser to test! // Parser to test!
// TODO: Change this as you finish parsers // TODO: Change this as you finish parsers
val parser = new ArithParser(scanner) val parser = new LoopParser(scanner)
val ast = parser.parseCode val ast = parser.parseCode
println("============= AST ================") println("============= AST ================")

@ -88,11 +88,11 @@ class Scanner(in: Reader[Char]) extends Reader[Tokens.Token] with Reporter {
// List of delimiters // List of delimiters
// TODO: Update this as delimiters are added to our language // TODO: Update this as delimiters are added to our language
val isDelim = Set('(',')') val isDelim = Set('(', ')', ';', '{', '}')
// List of keywords // List of keywords
// TODO: Update this as keywords are added to our language // TODO: Update this as keywords are added to our language
val isKeyword = Set[String]("val", "var") val isKeyword = Set[String]("val", "var", "if", "else", "while")
/* /*
* Extract a name from the stream * Extract a name from the stream
@ -429,9 +429,12 @@ class ArithParser(in: Scanner) extends Parser(in) {
def parseExpression(min: Int): Exp = { def parseExpression(min: Int): Exp = {
var res = parseUAtom var res = parseUAtom
// TODO: complete DONE? // TODO: complete DONE?
if (in.hasNext(isOperator)) { while (
in.hasNext(isOperator) &&
isInfixOp(min)(in.peek)
) {
val (op, pos) = getOperator val (op, pos) = getOperator
Prim(op, res, parseUAtom).withPos(pos) res = Prim(op, res, parseExpression(prec(op))).withPos(pos)
} }
res res
} }
@ -538,7 +541,9 @@ class BranchParser(in: Scanner) extends LetParser(in) {
} }
// TODO: remove ??? and complete the implementation. // TODO: remove ??? and complete the implementation.
override def parseSimpleExpression: Exp = in.peek match { override def parseSimpleExpression: Exp = {
print(in.peek)
in.peek match {
case Keyword("if") => case Keyword("if") =>
val pos = in.next().pos val pos = in.next().pos
accept('(') accept('(')
@ -546,6 +551,7 @@ class BranchParser(in: Scanner) extends LetParser(in) {
accept(')') accept(')')
val if_stmt = parseSimpleExpression val if_stmt = parseSimpleExpression
if (in.hasNext(_ == Keyword("else"))) { if (in.hasNext(_ == Keyword("else"))) {
in.next()
val else_stmt = parseSimpleExpression val else_stmt = parseSimpleExpression
If(cond, if_stmt, else_stmt).withPos(pos) If(cond, if_stmt, else_stmt).withPos(pos)
} }
@ -553,6 +559,7 @@ class BranchParser(in: Scanner) extends LetParser(in) {
case _ => super.parseSimpleExpression case _ => super.parseSimpleExpression
} }
} }
}
/* /*
* We can now introduce mutable variables using the 'var' keyword. * We can now introduce mutable variables using the 'var' keyword.
@ -596,9 +603,10 @@ class VariableParser(in: Scanner) extends BranchParser(in) {
// TODO: remove ??? and complete the implementation. // TODO: remove ??? and complete the implementation.
override def parseSimpleExpression = (in.peek, in.peek1) match { override def parseSimpleExpression = (in.peek, in.peek1) match {
case (Ident(x), Delim('=')) => case (Ident(x), Delim('=')) =>
val pos:Position = in.peek.pos val pos:Position = in.next().pos
accept('=')
VarAssign(x, parseSimpleExpression).withPos(pos) VarAssign(x, parseSimpleExpression).withPos(pos)
case _ => super.parseExpression case _ => super.parseSimpleExpression
} }
} }
@ -635,6 +643,7 @@ class LoopParser(in: Scanner) extends VariableParser(in) {
val cond = parseCondition val cond = parseCondition
accept(')') accept(')')
val simp = parseSimpleExpression val simp = parseSimpleExpression
accept(';')
val body = parseExpression val body = parseExpression
While(cond, simp, body).withPos(pos) While(cond, simp, body).withPos(pos)
case _ => case _ =>

@ -121,22 +121,22 @@ class SemanticAnalyzer(parser: Parser) extends Reporter {
analyze(v)(env) analyze(v)(env)
case Prim(op, lop, rop) => // Done case Prim(op, lop, rop) => // Done
if(!(isOperator(op) || isBOperator(op))) if(!(isOperator(op) || isBOperator(op)))
error("undefined primitive operator") error("undefined primitive operator", exp.pos)
analyze(lop)(env) analyze(lop)(env)
analyze(rop)(env) analyze(rop)(env)
case Let(x, a, b) => // val x = a; b case Let(x, a, b) => // val x = a; b
// Done: check variable reuse // Done: check variable reuse
if(!env.vars.contains(x)) if(env.vars.contains(x))
error(s"cannot assign variable $x") error(s"cannot assign variable $x", exp.pos)
analyze(a)(env) analyze(a)(env)
analyze(b)(env.withVal(x)) analyze(b)(env.withVal(x))
case Ref(x) => case Ref(x) =>
if (!env.vars.contains(x)) if (!env.vars.contains(x))
error(s"symbol $x not defined") error(s"symbol $x not defined", exp.pos)
// Done // Done
case Cond(op, l, r) => case Cond(op, l, r) =>
if (!isBOperator(op)) if (!isBOperator(op))
error(s"$op is not a boolean operator") error(s"$op is not a boolean operator", exp.pos)
analyze(l)(env) analyze(l)(env)
analyze(r)(env) analyze(r)(env)
// Done // Done
@ -146,13 +146,13 @@ class SemanticAnalyzer(parser: Parser) extends Reporter {
analyze(eBranch)(env) analyze(eBranch)(env)
case VarDec(x, rhs, body) => // var x = rhs; body case VarDec(x, rhs, body) => // var x = rhs; body
if (env.vars.contains(x)) if (env.vars.contains(x))
error(s"symbol $x already defined") error(s"symbol $x already defined", exp.pos)
analyze(rhs)(env) analyze(rhs)(env)
analyze(body)(env) analyze(body)(env.withVar(x))
// TODO // TODO
case VarAssign(x, rhs) => // x = rhs case VarAssign(x, rhs) => // x = rhs
if (!(env.vars.contains(x) && env.vars(x))) if (!(env.vars.contains(x) && env.vars(x)))
error(s"cannot assign $x: ${if(env.vars.contains(x))"immutable"else"undefined"}") error(s"cannot assign $x: ${if(env.vars.contains(x))"immutable"else"undefined"}", exp.pos)
analyze(rhs)(env) analyze(rhs)(env)
// TODO // TODO
case While(cond, lBody, body) => case While(cond, lBody, body) =>

Loading…
Cancel
Save