private Node and_or_ast(Terminal op, Node nleft, Node nright) { Node n = null; switch (op.TokenType) { case TokenType.and: var lbljmpzero = newLabel(); n = new Node(op, nleft, new Node(nilterminal(), new Node(new Terminal(TokenType.jmpzero, lbljmpzero, currenttoken.LN, currenttoken.CP)), new Node(nilterminal(), nright, new Node(new Terminal(TokenType.label, lbljmpzero, currenttoken.LN, currenttoken.CP))))); break; case TokenType.or: var lbljmpnotz = newLabel(); n = new Node(op, nleft, new Node(nilterminal(), new Node(new Terminal(TokenType.jmpnotz, lbljmpnotz, currenttoken.LN, currenttoken.CP)), new Node(nilterminal(), nright, new Node(new Terminal(TokenType.label, lbljmpnotz, currenttoken.LN, currenttoken.CP))))); break; } return n; }
Node assignment() { var s = currenttoken.Value.ToString(); nexttoken(); expect(TokenType.assig); var op = new Terminal(TokenType.assig, s, currenttoken.LN, currenttoken.CP); nexttoken(); var r = new Node(new Terminal(TokenType.identlocal, s, currenttoken.LN, currenttoken.CP)); var l = expression_single(); return new Node(op, l, r); }
Node call(Node nleft) { if (currenttoken.TokenType == TokenType.lparen) { var tl = new Terminal(TokenType.list, currenttoken.LN, currenttoken.CP); var bindings = new Node(tl); nexttoken(); if (currenttoken.TokenType != TokenType.rparen) { bindings = build_list(); } expect(TokenType.rparen); nexttoken(); var op = new Terminal(TokenType.eval, currenttoken.LN, currenttoken.CP); var deep = new Node(op, bindings, nleft); // keep consuming evaluations. return call(deep); } else return nleft; }
public Node(Terminal o, Node izq, Node der) { this.o = o; this.left = izq; this.right = der; }
Node term() { Node nleft = factor_negated(); if (currenttoken.TokenType == TokenType.times || currenttoken.TokenType == TokenType.slash || currenttoken.TokenType == TokenType.perc) { Terminal op = currenttoken; nexttoken(); Node nright = term(); Node n = new Node(op, nleft, nright); return n; } else return nleft; }
Node factor_negated() { Node nleft = null; if (currenttoken.TokenType == TokenType.not) { Terminal op = currenttoken; nexttoken(); nleft = expression_evaluated(); Node n = new Node(op, nleft, null); return n; } else return expression_evaluated(); }
Node factor() { Node f = null; switch (currenttoken.TokenType) { case TokenType.ident: f = new Node(currenttoken); break; case TokenType.number: f = new Node(currenttoken); break; case TokenType.str: f = new Node(currenttoken); break; case TokenType.lbrac: nexttoken(); if (currenttoken.TokenType == TokenType.rbrac) { var empty = new Terminal(TokenType.list, currenttoken.LN, currenttoken.CP); f = new Node(empty); } else f = build_list(); expect(TokenType.rbrac); break; case TokenType.lparen: nexttoken(); f = expression(); expect(TokenType.rparen); break; case TokenType.lcurly: nexttoken(); expect(TokenType.ident); f = new Node(currenttoken); nexttoken(); expect(TokenType.rcurly); break; default: var msg = string.Format(Strings.Expression_Syntax_error, currenttoken.LN, currenttoken.CP); error(msg); break; } nexttoken(); return f; }
Node expression_sum() { Node nleft = term(); if (currenttoken.TokenType == TokenType.plus || currenttoken.TokenType == TokenType.minus) { Terminal op = currenttoken; nexttoken(); Node nright = expression_sum(); Node n = new Node(op, nleft, nright); return n; } else return nleft; }
Node expression_logic() { Node nleft = expression_sum(); if (currenttoken.TokenType == TokenType.eq || currenttoken.TokenType == TokenType.gt || currenttoken.TokenType == TokenType.gteq || currenttoken.TokenType == TokenType.lt || currenttoken.TokenType == TokenType.lteq || currenttoken.TokenType == TokenType.neq) { Terminal op = currenttoken; nexttoken(); Node nright = expression_logic(); Node n = new Node(op, nleft, nright); return n; } else return nleft; }
Node expression_cond() { Node whentrue = expression_andor(); if (currenttoken.TokenType == TokenType.iff) { nexttoken(); Node condition = expression_andor(); expect(TokenType.els); nexttoken(); Node whenfalse = expression_cond(); var n = new Node(new Terminal(TokenType.iff, currenttoken.LN, currenttoken.CP), and_or_ast(new Terminal(TokenType.or, currenttoken.LN, currenttoken.CP), and_or_ast(new Terminal(TokenType.and, currenttoken.LN, currenttoken.CP), condition, whentrue), whenfalse), null); return n; } else return whentrue; }