pass all tests

master
Chiyoda Sumika 1 year ago
parent 441add2c71
commit 9562517e28

@ -42,6 +42,9 @@ OPTION: compX86, intStack, intValue (default)""")
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)
println("==================================\n")
@ -51,7 +54,7 @@ OPTION: compX86, intStack, intValue (default)""")
// Parser to test!
// TODO: Change this as you finish parsers
val parser = new ArithParser(scanner)
val parser = new LoopParser(scanner)
val ast = parser.parseCode
println("============= AST ================")

@ -88,11 +88,11 @@ class Scanner(in: Reader[Char]) extends Reader[Tokens.Token] with Reporter {
// List of delimiters
// TODO: Update this as delimiters are added to our language
val isDelim = Set('(',')')
val isDelim = Set('(', ')', ';', '{', '}')
// List of keywords
// 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
@ -429,9 +429,12 @@ class ArithParser(in: Scanner) extends Parser(in) {
def parseExpression(min: Int): Exp = {
var res = parseUAtom
// TODO: complete DONE?
if (in.hasNext(isOperator)) {
while (
in.hasNext(isOperator) &&
isInfixOp(min)(in.peek)
) {
val (op, pos) = getOperator
Prim(op, res, parseUAtom).withPos(pos)
res = Prim(op, res, parseExpression(prec(op))).withPos(pos)
}
res
}
@ -538,7 +541,9 @@ class BranchParser(in: Scanner) extends LetParser(in) {
}
// 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") =>
val pos = in.next().pos
accept('(')
@ -546,6 +551,7 @@ class BranchParser(in: Scanner) extends LetParser(in) {
accept(')')
val if_stmt = parseSimpleExpression
if (in.hasNext(_ == Keyword("else"))) {
in.next()
val else_stmt = parseSimpleExpression
If(cond, if_stmt, else_stmt).withPos(pos)
}
@ -553,6 +559,7 @@ class BranchParser(in: Scanner) extends LetParser(in) {
case _ => super.parseSimpleExpression
}
}
}
/*
* 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.
override def parseSimpleExpression = (in.peek, in.peek1) match {
case (Ident(x), Delim('=')) =>
val pos:Position = in.peek.pos
val pos:Position = in.next().pos
accept('=')
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
accept(')')
val simp = parseSimpleExpression
accept(';')
val body = parseExpression
While(cond, simp, body).withPos(pos)
case _ =>

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

Loading…
Cancel
Save