diff --git a/sources/zweic/Parser.scala b/sources/zweic/Parser.scala index 3974ef7..6b898bb 100755 --- a/sources/zweic/Parser.scala +++ b/sources/zweic/Parser.scala @@ -13,6 +13,7 @@ class Parser(in: java.io.InputStream) extends Scanner(in) { import Tokens._; + import Tree._; var pushedBack: Option[Triple[Int,String,Token]] = None; @@ -315,13 +316,21 @@ * MySumExpression = Term [ SumOp SumExpression ] */ private def sumExpression(): Expr = { - val left = term(); - if ( token == ADD || token == SUB || token == OR ) { - val op = sumOp(); - val right = sumExpression(); - return Binop(op, left, right); + var left = term(); + if ( token == ADD || token == SUB ) { + return Binop(sumOp(), left, sumExpression()); + } else { + if ( token == OR ) { + return Unop(Operators.NOT, + Binop(Operators.AND, + Unop(Operators.NOT, left), + Unop(Operators.NOT, sumExpression()) + ) + ); + } else { + return left; + } } - return left; } /** @@ -346,40 +355,51 @@ return left; } + private def string(str: String): New = str match { + case st::xs => return new New(Name("Cons"), IntLit(Int(st))::string(xs)::Nil) + case _ => return new New(Name("Nil"), Nil) + } + /** * Factor = look it up yourself! */ private def factor(): Expr = { + var name = chars; + var rval:Expr = null; token match { - case IDENT => nextToken; - case NUMBER => nextToken; - case STRING => nextToken; - case TRUE => nextToken; - case FALSE => nextToken; - case THIS => nextToken; - case NULLFACTOR => nextToken; - case READINT => nextToken; - case READCHAR => nextToken; - case LPAREN => nextToken; expression(); accept(RPAREN); - case LACCOLADE => block(); - case NEW => nextToken; accept(IDENT); params(); + case IDENT => nextToken; rval = Ident(Name(chars)); + case NUMBER => nextToken; rval = IntLit(Integer.parseInt(chars)); + case STRING => nextToken; rval = string(name); + case TRUE => nextToken; rval = IntLit(1); + case FALSE => nextToken; rval = IntLit(0); + case THIS => nextToken; rval = Ident(Name("this")); + case NULLFACTOR => nextToken; rval = NullLit(); + case READINT => nextToken; rval = ReadInt(); + case READCHAR => nextToken; rval = ReadChar(); + case LPAREN => nextToken; rval = expression(); accept(RPAREN); + case LACCOLADE => rval = block(); + case NEW => nextToken; accept(IDENT); rval = New(Name(name), params()); case _ => error("Identifier, Number, String, 'true', 'false', 'this', 'null', 'readInt', 'readChar', '(Expression)', '{Block}' or 'new'"); } while ( check(DOT) ) { accept(IDENT); if ( token == LPAREN ) { - params(); + rval = Call(rval, Name(name), params()); + } else { + rval = Select(rval, Name(name)); } + name = chars; } - return null; + return rval; } /** * Expressions = [ Expression { "," Expression } ] */ private def expressions(): List[Expr] = { + var rval:List[Expr] = Nil; if ( token == IF || token == SUB || token == NOT || token == IDENT || token == NUMBER || token == STRING || token == TRUE @@ -387,51 +407,51 @@ || token == NULLFACTOR || token == READINT || token == READCHAR || token == LPAREN || token == NEW || token == LACCOLADE ) { - expression(); + rval = expression()::rval; while ( check(PERIOD) ) { - expression(); + rval = expression()::rval; } } - return null; + return rval.reverse; } /** * Params = "(" Expressions ")" */ - private def params(): Tree = { + private def params(): List[Expr] = { accept(LPAREN); - expressions(); + var exprs = expressions(); accept(RPAREN); - return null; + return exprs; } /** * ProdOp = "*" | "/" | "%" | "&&" */ - private def prodOp(): Operators = token match { - case MUL => nextToken; return null; - case DIV => nextToken; return null; - case MOD => nextToken; return null; - case AND => nextToken; return null; + private def prodOp(): Operators.Operator = token match { + case MUL => nextToken; return Operators.MUL; + case DIV => nextToken; return Operators.DIV; + case MOD => nextToken; return Operators.MOD; + case AND => nextToken; return Operators.AND; case _ => error("'*', '/', '%' or '&&' token"); return null; } /** * NegateOp = "-" | "!" */ - private def negateOp(): Operators = token match { - case SUB => nextToken; return null; - case NOT => nextToken; return null; + private def negateOp(): Operators.Operator = token match { + case SUB => nextToken; return Operators.NEG; + case NOT => nextToken; return Operators.NOT; case _ => error("'-' or '!' token"); return null; } /** * SumOp = "+" | "-" | "||" */ - private def sumOp(): Operators = token match { - case ADD => nextToken; return null; - case SUB => nextToken; return null; - case OR => nextToken; return null; + private def sumOp(): Operators.Operator = token match { + case ADD => nextToken; return Operators.ADD; + case SUB => nextToken; return Operators.SUB; + // case OR => nextToken; return null; // no longer needed case _ => error("'+', '-' or '||' token"); return null; } @@ -439,13 +459,13 @@ /** * CompOp = "==" | "!" | "<" | ">" | "<=" | ">=" */ - private def compOp(): Operators = token match { - case EQ => nextToken; return null; - case NE => nextToken; return null; - case LT => nextToken; return null; - case GT => nextToken; return null; - case LE => nextToken; return null; - case GE => nextToken; return null; + private def compOp(): Operators.Operator = token match { + case EQ => nextToken; return Operators.EQ; + case NE => nextToken; return Operators.NE; + case LT => nextToken; return Operators.LT; + case GT => nextToken; return Operators.GT; + case LE => nextToken; return Operators.LE; + case GE => nextToken; return Operators.GE; case _ => error("comparison operator ('==', '!', '<', '>', '<=', '>=')"); return null; } } diff --git a/sources/zweic/Tree.scala b/sources/zweic/Tree.scala index 234698b..758024d 100755 --- a/sources/zweic/Tree.scala +++ b/sources/zweic/Tree.scala @@ -113,10 +113,10 @@ case class New(name: Name, args: List[Expr]) extends Expr; /* E = Select E name */ -case class Select(varname: Expr, name: Name) extends Expr; +case class Select(obj: Expr, varname: Name) extends Expr; /* E = Call E name { E } */ -case class Call(func: Expr, name: Name, args: List[Expr]) extends Expr; +case class Call(obj: Expr, funcname: Name, args: List[Expr]) extends Expr; /* E = NullLit */ case class NullLit extends Expr;