Expr additive_exprP(Expr leftExpr) { switch(currentToken.Tipo){ case TokenType.ADDITION: match(TokenType.ADDITION); Expr rightadd = multiplicative_expr(); AdditionExpr additionexpr = new AdditionExpr(leftExpr, rightadd); return additive_exprP(additionexpr); case TokenType.SUBSTRACTION: match(TokenType.SUBSTRACTION); Expr rightsub = multiplicative_expr(); SubstractionExpr substractionexpr = new SubstractionExpr(leftExpr, rightsub); return additive_exprP(substractionexpr); default: return leftExpr;//null } }
public override AST.Expr GetExpr(AST.Env env) { AST.Expr expr = this.expr.GetExpr(env); if (!expr.type.IsIntegral) { throw new InvalidOperationException("Expected integral type."); } expr = AST.TypeCast.IntegralPromotion(expr).Item1; if (expr.IsConstExpr) { switch (expr.type.kind) { case AST.ExprType.Kind.LONG: return new AST.ConstLong(~((AST.ConstLong)expr).value, env); case AST.ExprType.Kind.ULONG: return new AST.ConstULong(~((AST.ConstULong)expr).value, env); default: throw new InvalidOperationException(); } } return new AST.BitwiseNot(expr, expr.type); }
//E' Expr multiplicative_exprP(Expr leftExpr) { switch (currentToken.Tipo) { case TokenType.MULTIPLICATION: match(TokenType.MULTIPLICATION); Expr rightmul = unary_expr(); MultiplicationExpr multiplicationexpr = new MultiplicationExpr(leftExpr, rightmul); return multiplicative_exprP(multiplicationexpr); case TokenType.DIVISION: match(TokenType.DIVISION); Expr rightdiv = unary_expr(); DivisionExpr divisionexpr = new DivisionExpr(leftExpr, rightdiv); return multiplicative_exprP(divisionexpr); case TokenType.REMAINDER: match(TokenType.REMAINDER); Expr rightmod = unary_expr(); RemainderExpr remainderexpr = new RemainderExpr(leftExpr, rightmod); return multiplicative_exprP(remainderexpr); default: return leftExpr;//null } }
public Enumerator(String _name, Expr _init) { enum_name = _name; enum_init = _init; }
public FuncCall(Expr func, IReadOnlyList<Expr> args) { this.func = func; this.args = args; }
public ConditionalExpression(Expr cond, Expr true_expr, Expr false_expr) { this.cond = cond; this.true_expr = true_expr; this.false_expr = false_expr; }
public TypeCast(TypeName type_name, Expr expr) { this.type_name = type_name; this.expr = expr; }
public PreIncrement(Expr expr) { this.expr = expr; }
public ReturnStmt(Expr expr) { this.expr = expr; }
public IfStmt(Expr cond, Stmt stmt) { this.cond = cond; this.stmt = stmt; }
public IfElseStmt(Expr cond, Stmt true_stmt, Stmt false_stmt) { this.cond = cond; this.true_stmt = true_stmt; this.false_stmt = false_stmt; }
public ExprStmt(Expr expr) { this.expr = expr; }
public DoWhileStmt(Stmt body, Expr cond) { this.body = body; this.cond = cond; }
Expr AND_exprP(Expr leftExpr) { if (peek(TokenType.AND)) { match(TokenType.AND); Expr rightand = equal_expr(); AndExpr andexpr = new AndExpr(leftExpr, rightand); return AND_exprP(andexpr); } else return leftExpr;//null }
Expr OR_exprP(Expr leftExpr) { if (peek(TokenType.OR)) { match(TokenType.OR); Expr rightor = AND_expr(); OrExpr orexpr = new OrExpr(leftExpr, rightor); return OR_exprP(orexpr); } else return leftExpr;//null }
public override AST.Expr GetExpr(AST.Env env) { AST.Expr expr = this.expr.GetExpr(env); if (!expr.type.IsArith) { throw new InvalidOperationException("Expected arithmetic type."); } if (expr.type.IsIntegral) { expr = AST.TypeCast.IntegralPromotion(expr).Item1; } if (expr.IsConstExpr) { switch (expr.type.kind) { case AST.ExprType.Kind.LONG: return new AST.ConstLong(-((AST.ConstLong)expr).value, env); case AST.ExprType.Kind.ULONG: return new AST.ConstLong(-(Int32)((AST.ConstULong)expr).value, env); case AST.ExprType.Kind.FLOAT: return new AST.ConstFloat(-((AST.ConstFloat)expr).value, env); case AST.ExprType.Kind.DOUBLE: return new AST.ConstDouble(-((AST.ConstDouble)expr).value, env); default: throw new InvalidOperationException(); } } return new AST.Negative(expr, expr.type); }
public Positive(Expr expr) { this.expr = expr; }
public override Tuple<AST.Env, AST.Stmt> GetStmt(AST.Env env) { AST.Expr expr = this.expr.GetExpr(env); expr = AST.TypeCast.MakeCast(expr, env.GetCurrentFunction().ret_t); return new Tuple<AST.Env, AST.Stmt>(env, new AST.ReturnStmt(expr)); }
public PostIncrement(Expr expr) { this.expr = expr; }
public SwitchStmt(Expr expr, Stmt stmt) { this.expr = expr; this.stmt = stmt; }
public SizeofExpr(Expr expr) { this.expr = expr; }
public WhileStmt(Expr cond, Stmt body) { this.cond = cond; this.body = body; }
public Dereference(Expr expr) { this.expr = expr; }
public LogicalNot(Expr expr) { this.expr = expr; }
public override AST.Expr GetExpr(AST.Env env) { AST.Expr cond = this.cond.GetExpr(env); if (!cond.type.IsScalar) { throw new InvalidOperationException("Expected a scalar condition in conditional expression."); } if (cond.type.IsIntegral) { cond = AST.TypeCast.IntegralPromotion(cond).Item1; } AST.Expr true_expr = this.true_expr.GetExpr(env); AST.Expr false_expr = this.false_expr.GetExpr(env); // 1. if both true_expr and false_Expr have arithmetic types: // perform usual arithmetic conversion if (true_expr.type.IsArith && false_expr.type.IsArith) { var r_cast = AST.TypeCast.UsualArithmeticConversion(true_expr, false_expr); true_expr = r_cast.Item1; false_expr = r_cast.Item2; return new AST.ConditionalExpr(cond, true_expr, false_expr, true_expr.type); } if (true_expr.type.kind != false_expr.type.kind) { throw new InvalidOperationException("Operand types not match in conditional expression."); } switch (true_expr.type.kind) { // 2. if both true_expr and false_expr have struct or union type // make sure they are compatible case AST.ExprType.Kind.STRUCT_OR_UNION: if (!true_expr.type.EqualType(false_expr.type)) { throw new InvalidOperationException("Expected compatible types in conditional expression."); } return new AST.ConditionalExpr(cond, true_expr, false_expr, true_expr.type); // 3. if both true_expr and false_expr have void type // return void case AST.ExprType.Kind.VOID: return new AST.ConditionalExpr(cond, true_expr, false_expr, true_expr.type); // 4. if both true_expr and false_expr have pointer type case AST.ExprType.Kind.POINTER: // if either points to void, convert to void * if (((AST.TPointer)true_expr.type).ref_t.kind == AST.ExprType.Kind.VOID || ((AST.TPointer)false_expr.type).ref_t.kind == AST.ExprType.Kind.VOID) { return new AST.ConditionalExpr(cond, true_expr, false_expr, new AST.TPointer(new AST.TVoid())); } throw new NotImplementedException("More comparisons here."); default: throw new InvalidOperationException("Expected compatible types in conditional expression."); } }
public override AST.Expr GetExpr(AST.Env env) { AST.Expr expr = this.expr.GetExpr(env); if (!expr.type.IsArith) { throw new InvalidOperationException("Expected arithmetic type."); } if (expr.type.IsIntegral) { expr = AST.TypeCast.IntegralPromotion(expr).Item1; } if (expr.IsConstExpr) { Boolean is_zero; switch (expr.type.kind) { case AST.ExprType.Kind.LONG: is_zero = ((AST.ConstLong)expr).value == 0; break; case AST.ExprType.Kind.ULONG: is_zero = ((AST.ConstULong)expr).value == 0; break; case AST.ExprType.Kind.FLOAT: is_zero = ((AST.ConstFloat)expr).value == 0; break; case AST.ExprType.Kind.DOUBLE: is_zero = ((AST.ConstDouble)expr).value == 0; break; default: throw new InvalidOperationException(); } return new AST.ConstLong(Convert.ToInt32(is_zero), env); } return new AST.LogicalNot(expr, new AST.TLong(expr.type.is_const, expr.type.is_volatile)); }
public Attribute(Expr expr, Variable attrib) { this.expr = expr; this.attrib = attrib; }
public Negative(Expr expr) { this.expr = expr; }
public InitExpr(Expr expr) : base(Kind.EXPR) { this.expr = expr; }
public BitwiseNot(Expr expr) { this.expr = expr; }