public override ABT.Expr GetExpr(ABT.Env env) { ABT.Expr expr = this.Expr.GetExpr(env); if (!expr.Type.IsIntegral) { throw new InvalidOperationException("Expected integral Type."); } expr = ABT.TypeCast.IntegralPromotion(expr).Item1; if (expr.IsConstExpr) { switch (expr.Type.Kind) { case ABT.ExprTypeKind.LONG: return(new ABT.ConstLong(~((ABT.ConstLong)expr).Value, env)); case ABT.ExprTypeKind.ULONG: return(new ABT.ConstULong(~((ABT.ConstULong)expr).Value, env)); default: throw new InvalidOperationException(); } } return(new ABT.BitwiseNot(expr)); }
public static ABT.Expr GetPointerSubtraction(ABT.Expr ptr, ABT.Expr offset) { if (ptr.Type.Kind != ABT.ExprTypeKind.POINTER) { throw new InvalidOperationException("Error: expect a pointer"); } if (offset.Type.Kind != ABT.ExprTypeKind.LONG) { throw new InvalidOperationException("Error: expect an integer"); } if (ptr.IsConstExpr && offset.IsConstExpr) { Int32 baseAddressValue = (Int32)((ABT.ConstPtr)ptr).Value; Int32 scaleFactorValue = ((ABT.PointerType)(ptr.Type)).RefType.SizeOf; Int32 offsetValue = ((ABT.ConstLong)offset).Value; return(new ABT.ConstPtr((UInt32)(baseAddressValue - scaleFactorValue * offsetValue), ptr.Type, offset.Env)); } return(ABT.TypeCast.ToPointer(new ABT.Sub( ABT.TypeCast.FromPointer(ptr, new ABT.LongType(ptr.Type.IsConst, ptr.Type.IsVolatile), ptr.Env), new ABT.Multiply( offset, new ABT.ConstLong(((ABT.PointerType)(ptr.Type)).RefType.SizeOf, offset.Env) ) ), ptr.Type, offset.Env )); }
public ABT.Expr GetPointerAddition(ABT.Expr ptr, ABT.Expr offset, Boolean order = true) { if (ptr.Type.Kind != ABT.ExprTypeKind.POINTER) { throw new InvalidOperationException(); } if (offset.Type.Kind != ABT.ExprTypeKind.LONG) { throw new InvalidOperationException(); } var env = order ? ptr.Env : offset.Env; if (ptr.IsConstExpr && offset.IsConstExpr) { var baseValue = (Int32)((ABT.ConstPtr)ptr).Value; Int32 scaleValue = ((ABT.PointerType)(ptr.Type)).RefType.SizeOf; Int32 offsetValue = ((ABT.ConstLong)offset).Value; return(new ABT.ConstPtr((UInt32)(baseValue + scaleValue * offsetValue), ptr.Type, env)); } var baseAddress = ABT.TypeCast.FromPointer(ptr, new ABT.LongType(ptr.Type.IsConst, ptr.Type.IsVolatile), ptr.Env); var scaleFactor = new ABT.Multiply( offset, new ABT.ConstLong(((ABT.PointerType)(ptr.Type)).RefType.SizeOf, env) ); var type = new ABT.LongType(offset.Type.IsConst, offset.Type.IsVolatile); var add = order ? new ABT.Add(baseAddress, scaleFactor) : new ABT.Add(scaleFactor, baseAddress); return(ABT.TypeCast.ToPointer(add, ptr.Type, env)); }
public override ABT.Expr GetExpr(ABT.Env env) { ABT.Expr expr = this.Expr.GetExpr(env); if (!expr.Type.IsScalar) { throw new InvalidOperationException("Expected a scalar."); } return(new ABT.PostDecrement(expr)); }
public override Tuple <ABT.Env, ABT.Stmt> GetStmt(ABT.Env env) { ABT.Expr expr = this.Expr.GetExpr(env); Tuple <ABT.Env, ABT.Stmt> r_stmt = this.Stmt.GetStmt(env); env = r_stmt.Item1; ABT.Stmt stmt = r_stmt.Item2; return(new Tuple <ABT.Env, ABT.Stmt>(env, new ABT.SwitchStmt(expr, stmt))); }
public override ABT.Expr GetExpr(ABT.Env env) { ABT.Expr expr = this.Expr.GetExpr(env); if (!expr.Type.IsArith) { throw new InvalidOperationException("Expected arithmetic Type."); } return(expr); }
public override ABT.Expr GetExpr(ABT.Env env) { ABT.Expr expr = this.Expr.GetExpr(env); String name = this.Member; if (expr.Type.Kind != ABT.ExprTypeKind.STRUCT_OR_UNION) { throw new InvalidOperationException("Must get the attribute from a struct or union."); } ABT.Utils.StoreEntry entry = (expr.Type as ABT.StructOrUnionType).Attribs.First(_ => _.name == name); ABT.ExprType type = entry.type; return(new ABT.Attribute(expr, name, type)); }
public override Tuple <ABT.Env, ABT.Stmt> GetStmt(ABT.Env env) { ABT.Expr cond = this.Cond.GetExpr(env); if (!cond.Type.IsScalar) { throw new InvalidOperationException("Error: expected scalar Type"); } Tuple <ABT.Env, ABT.Stmt> r_stmt = this.Stmt.GetStmt(env); env = r_stmt.Item1; ABT.Stmt stmt = r_stmt.Item2; return(new Tuple <ABT.Env, ABT.Stmt>(env, new ABT.IfStmt(cond, stmt))); }
public override ABT.Expr GetExpr(ABT.Env env) { ABT.Expr expr = this.Expr.GetExpr(env); if (expr.Type.Kind != ABT.ExprTypeKind.POINTER) { throw new InvalidOperationException("Expected a pointer."); } ABT.ExprType type = ((ABT.PointerType)expr.Type).RefType; if (type.Kind == ABT.ExprTypeKind.STRUCT_OR_UNION && !((ABT.StructOrUnionType)type).IsComplete) { throw new InvalidOperationException("Cannot dereference incomplete Type."); } return(new ABT.Dereference(expr, type)); }
public override Tuple <ABT.Env, ABT.Stmt> GetStmt(ABT.Env env) { Tuple <ABT.Env, ABT.Stmt> r_body = this.Body.GetStmt(env); env = r_body.Item1; ABT.Stmt body = r_body.Item2; ABT.Expr cond = this.Cond.GetExpr(env); env = cond.Env; if (!cond.Type.IsScalar) { throw new InvalidOperationException("Error: conditional expression in while Loop must be scalar."); } return(new Tuple <ABT.Env, ABT.Stmt>(env, new ABT.DoWhileStmt(body, cond))); }
public override Tuple <ABT.Env, ABT.Stmt> GetStmt(ABT.Env env) { ABT.Expr expr = this.Expr.GetExpr(env); env = expr.Env; expr = ABT.TypeCast.MakeCast(expr, new ABT.LongType()); if (!expr.IsConstExpr) { throw new InvalidOperationException("case Expr not const"); } Int32 value = ((ABT.ConstLong)expr).Value; Tuple <ABT.Env, ABT.Stmt> r_stmt = this.Stmt.GetStmt(env); env = r_stmt.Item1; return(new Tuple <ABT.Env, ABT.Stmt>(env, new ABT.CaseStmt(value, r_stmt.Item2))); }
public override ABT.Expr GetExpr(ABT.Env env) { ABT.Expr expr = this.Expr.GetExpr(env); if (!expr.Type.IsArith) { throw new InvalidOperationException("Expected arithmetic Type."); } if (expr.Type.IsIntegral) { expr = ABT.TypeCast.IntegralPromotion(expr).Item1; } if (expr.IsConstExpr) { switch (expr.Type.Kind) { case ABT.ExprTypeKind.LONG: return(new ABT.ConstLong(-((ABT.ConstLong)expr).Value, env)); case ABT.ExprTypeKind.ULONG: return(new ABT.ConstLong(-(Int32)((ABT.ConstULong)expr).Value, env)); case ABT.ExprTypeKind.FLOAT: return(new ABT.ConstFloat(-((ABT.ConstFloat)expr).Value, env)); case ABT.ExprTypeKind.DOUBLE: return(new ABT.ConstDouble(-((ABT.ConstDouble)expr).Value, env)); default: throw new InvalidOperationException(); } } return(new ABT.Negative(expr)); }
public override ABT.Expr GetExpr(ABT.Env env) { ABT.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 = ABT.TypeCast.IntegralPromotion(cond).Item1; } ABT.Expr true_expr = this.TrueExpr.GetExpr(env); ABT.Expr false_expr = this.FalseExpr.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 = ABT.TypeCast.UsualArithmeticConversion(true_expr, false_expr); true_expr = r_cast.Item1; false_expr = r_cast.Item2; return(new ABT.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 ABT.ExprTypeKind.STRUCT_OR_UNION: if (!true_expr.Type.EqualType(false_expr.Type)) { throw new InvalidOperationException("Expected compatible types in conditional expression."); } return(new ABT.ConditionalExpr(cond, true_expr, false_expr, true_expr.Type)); // 3. if both true_expr and false_expr have void Type // return void case ABT.ExprTypeKind.VOID: return(new ABT.ConditionalExpr(cond, true_expr, false_expr, true_expr.Type)); // 4. if both true_expr and false_expr have pointer Type case ABT.ExprTypeKind.POINTER: // if either points to void, convert to void * if (((ABT.PointerType)true_expr.Type).RefType.Kind == ABT.ExprTypeKind.VOID || ((ABT.PointerType)false_expr.Type).RefType.Kind == ABT.ExprTypeKind.VOID) { return(new ABT.ConditionalExpr(cond, true_expr, false_expr, new ABT.PointerType(new ABT.VoidType()))); } throw new NotImplementedException("More comparisons here."); default: throw new InvalidOperationException("Expected compatible types in conditional expression."); } }
public abstract ABT.Expr ConstructExpr(ABT.Expr left, ABT.Expr right, ABT.ExprType type);
public override ABT.Expr ConstructExpr(ABT.Expr left, ABT.Expr right, ABT.ExprType type) => new ABT.RShift(left, right);
public override ABT.Expr ConstructExpr(ABT.Expr left, ABT.Expr right, ABT.ExprType type) => new ABT.LogicalOr(left, right);
public override ABT.Expr ConstructExpr(ABT.Expr left, ABT.Expr right, ABT.ExprType type) => new ABT.Greater(left, right);
public override ABT.Expr ConstructExpr(ABT.Expr left, ABT.Expr right, ABT.ExprType type) => new ABT.NotEqual(left, right);
public override ABT.Expr GetExpr(ABT.Env env) { ABT.Expr expr = this.Expr.GetExpr(env); return(new ABT.Reference(expr)); }
public override ABT.Expr GetExpr(ABT.Env env) { ABT.Expr expr = this.Expr.GetExpr(env); return(new ABT.ConstULong((UInt32)expr.Type.SizeOf, env)); }
public override ABT.Expr GetExpr(ABT.Env env) { // Step 1: get arguments passed into the function. // Note that currently the arguments are not casted based on the prototype. var args = this.Args.Select(_ => _.GetExpr(env)).ToList(); // A special case: // If we cannot find the function prototype in the environment, make one up. // This function returns int. // Update the environment to add this function Type. if ((this.Func is Variable) && env.Find((this.Func as Variable).Name).IsNone) { // TODO: get this env used. env = env.PushEntry(ABT.Env.EntryKind.TYPEDEF, (this.Func as Variable).Name, ABT.FunctionType.Create(new ABT.LongType(true), args.ConvertAll(_ => Tuple.Create("", _.Type)), false ) ); } // Step 2: get function expression. ABT.Expr func = this.Func.GetExpr(env); // Step 3: get the function Type. ABT.FunctionType func_type; switch (func.Type.Kind) { case ABT.ExprTypeKind.FUNCTION: func_type = func.Type as ABT.FunctionType; break; case ABT.ExprTypeKind.POINTER: var ref_t = (func.Type as ABT.PointerType).RefType; if (!(ref_t is ABT.FunctionType)) { throw new InvalidOperationException("Expected a function pointer."); } func_type = ref_t as ABT.FunctionType; break; default: throw new InvalidOperationException("Expected a function in function call."); } Int32 num_args_prototype = func_type.Args.Count; Int32 num_args_actual = args.Count; // If this function doesn't take varargs, make sure the number of arguments match that in the prototype. if (!func_type.HasVarArgs && num_args_actual != num_args_prototype) { throw new InvalidOperationException("Number of arguments mismatch."); } // Anyway, you can't call a function with fewer arguments than the prototype. if (num_args_actual < num_args_prototype) { throw new InvalidOperationException("Too few arguments."); } // Make implicit cast. args = args.GetRange(0, num_args_prototype).Zip(func_type.Args, (arg, entry) => ABT.TypeCast.MakeCast(arg, entry.type) ).Concat(args.GetRange(num_args_prototype, num_args_actual - num_args_prototype)).ToList(); return(new ABT.FuncCall(func, func_type, args)); }
public override ABT.Expr GetExpr(ABT.Env env) { ABT.ExprType type = Semant(this.TypeName.GetExprType, ref env); ABT.Expr expr = this.Expr.GetExpr(env); return(ABT.TypeCast.MakeCast(expr, type)); }
public override ABT.Expr ConstructExpr(ABT.Expr left, ABT.Expr right, ABT.ExprType type) => new ABT.Multiply(left, right);
public override ABT.Expr ConstructExpr(ABT.Expr left, ABT.Expr right, ABT.ExprType type) => new ABT.BitwiseOr(left, right);