public override ABT.Expr GetExpr(ABT.Env env) { Option <ABT.Env.Entry> entry_opt = env.Find(this.Name); if (entry_opt.IsNone) { throw new InvalidOperationException($"Cannot find variable '{this.Name}'"); } ABT.Env.Entry entry = entry_opt.Value; switch (entry.Kind) { case ABT.Env.EntryKind.TYPEDEF: throw new InvalidOperationException($"Expected a variable '{this.Name}', not a typedef."); case ABT.Env.EntryKind.ENUM: return(new ABT.ConstLong(entry.Offset, env)); case ABT.Env.EntryKind.FRAME: case ABT.Env.EntryKind.GLOBAL: case ABT.Env.EntryKind.STACK: return(new ABT.Variable(entry.Type, this.Name, env)); default: throw new InvalidOperationException($"Cannot find variable '{this.Name}'"); } }
public static R Semant <R>(Func <ABT.Env, ISemantReturn <R> > semantFunc, ref ABT.Env env) { var semantReturn = semantFunc(env); env = semantReturn.Env; return(semantReturn.Value); }
public static ABT.Expr SemantExpr(Func <ABT.Env, ABT.Expr> semantFunc, ref ABT.Env env) { var semantReturn = semantFunc(env); env = semantReturn.Env; return(semantReturn); }
public override Tuple <ABT.Env, ABT.Stmt> GetStmt(ABT.Env env) { env = env.InScope(); List <Tuple <ABT.Env, ABT.Decln> > declns = new List <Tuple <ABT.Env, ABT.Decln> >(); List <Tuple <ABT.Env, ABT.Stmt> > stmts = new List <Tuple <ABT.Env, ABT.Stmt> >(); foreach (Decln decln in this.Declns) { //Tuple<AST.Env, List<Tuple<AST.Env, AST.Decln>>> r_decln = decln.GetDeclns_(env); //env = r_decln.Item1; //declns.AddRange(r_decln.Item2); var declns_ = Semant(decln.GetDeclns, ref env); declns.AddRange(declns_); } foreach (Stmt stmt in this.Stmts) { Tuple <ABT.Env, ABT.Stmt> r_stmt = stmt.GetStmt(env); env = r_stmt.Item1; stmts.Add(r_stmt); } env = env.OutScope(); return(new Tuple <ABT.Env, ABT.Stmt>(env, new ABT.CompoundStmt(declns, stmts))); }
public override Tuple <ABT.Env, ABT.Stmt> GetStmt(ABT.Env env) { var expr = this.Expr.Map(_ => _.GetExpr(env)); expr = expr.Map(_ => ABT.TypeCast.MakeCast(_, env.GetCurrentFunction().ReturnType)); return(new Tuple <ABT.Env, ABT.Stmt>(env, new ABT.ReturnStmt(expr))); }
public override Tuple <ABT.Env, ABT.Stmt> GetStmt(ABT.Env env) { var expr = this.Expr.Map(_ => _.GetExpr(env)); env = expr.IsSome ? expr.Value.Env : env; return(new Tuple <ABT.Env, ABT.Stmt>(env, new ABT.ExprStmt(expr))); }
public override ISemantReturn <ABT.ExprType> DecorateType(ABT.Env env, ABT.ExprType targetType) { var isConst = this.TypeQuals.Contains(TypeQual.CONST); var isVolatile = this.TypeQuals.Contains(TypeQual.VOLATILE); return(SemantReturn.Create(env, new ABT.PointerType(targetType, isConst, isVolatile))); }
public override Tuple <ABT.Env, ABT.Stmt> GetStmt(ABT.Env env) { Option <ABT.Expr> init = this.Init.Map(_ => _.GetExpr(env)); if (init.IsSome) { env = init.Value.Env; } Option <ABT.Expr> cond = this.Cond.Map(_ => _.GetExpr(env)); if (cond.IsSome) { env = cond.Value.Env; } if (cond.IsSome && !cond.Value.Type.IsScalar) { throw new InvalidOperationException("Error: conditional expression in while Loop must be scalar."); } Option <ABT.Expr> loop = this.Loop.Map(_ => _.GetExpr(env)); if (loop.IsSome) { env = loop.Value.Env; } Tuple <ABT.Env, ABT.Stmt> r_body = this.Body.GetStmt(env); env = r_body.Item1; ABT.Stmt body = r_body.Item2; return(new Tuple <ABT.Env, ABT.Stmt>(env, new ABT.ForStmt(init, cond, loop, body))); }
public override Tuple <ABT.Env, ABT.Stmt> GetStmt(ABT.Env env) { 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.LabeledStmt(this.Label, r_stmt.Item2))); }
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 override ABT.Expr GetExpr(ABT.Env env) { var left = SemantExpr(this.Left, ref env); var right = SemantExpr(this.Right, ref env); right = ABT.TypeCast.MakeCast(right, left.Type); return(new ABT.Assign(left, right)); }
public override ISemantReturn <ABT.Initr> GetInitr(ABT.Env env) { var initrs = this.Initrs.ConvertAll( initr => Semant(initr.GetInitr, ref env) ); return(SemantReturn.Create(env, new ABT.InitList(initrs.ToList()))); }
public override ABT.Expr GetExpr(ABT.Env env) { var left = SemantExpr(this.Left, ref env); var right = SemantExpr(this.Right, ref env); if (left.Type is ABT.ArrayType) { left = ABT.TypeCast.MakeCast(left, new ABT.PointerType((left.Type as ABT.ArrayType).ElemType, left.Type.IsConst, left.Type.IsVolatile)); } if (right.Type is ABT.ArrayType) { right = ABT.TypeCast.MakeCast(right, new ABT.PointerType((right.Type as ABT.ArrayType).ElemType, right.Type.IsConst, right.Type.IsVolatile)); } var isConst = left.Type.IsConst || right.Type.IsConst; var isVolatile = left.Type.IsVolatile || right.Type.IsVolatile; if (left.Type.Kind == ABT.ExprTypeKind.POINTER) { // 1. ptr - ptr if (right.Type.Kind == ABT.ExprTypeKind.POINTER) { ABT.PointerType leftType = (ABT.PointerType)(left.Type); ABT.PointerType rightType = (ABT.PointerType)(right.Type); if (!leftType.RefType.EqualType(rightType.RefType)) { throw new InvalidOperationException("The 2 pointers don't match."); } Int32 scale = leftType.RefType.SizeOf; if (left.IsConstExpr && right.IsConstExpr) { return(new ABT.ConstLong((Int32)(((ABT.ConstPtr)left).Value - ((ABT.ConstPtr)right).Value) / scale, env)); } return(new ABT.Divide( new ABT.Sub( ABT.TypeCast.MakeCast(left, new ABT.LongType(isConst, isVolatile)), ABT.TypeCast.MakeCast(right, new ABT.LongType(isConst, isVolatile)) ), new ABT.ConstLong(scale, env) )); } // 2. ptr - integral if (!right.Type.IsIntegral) { throw new InvalidOperationException("Expected an integral."); } right = ABT.TypeCast.MakeCast(right, new ABT.LongType(right.Type.IsConst, right.Type.IsVolatile)); return(GetPointerSubtraction(left, right)); } // 3. arith - arith return(base.GetExpr(env)); }
public override ABT.Expr GetExpr(ABT.Env env) { // 1. semant operands var left = SemantExpr(this.Left, ref env); var right = SemantExpr(this.Right, ref env); // 2. perform usual arithmetic conversion Tuple <ABT.Expr, ABT.Expr, ABT.ExprTypeKind> castReturn = ABT.TypeCast.UsualArithmeticConversion(left, right); left = castReturn.Item1; right = castReturn.Item2; var typeKind = castReturn.Item3; var isConst = left.Type.IsConst || right.Type.IsConst; var isVolatile = left.Type.IsVolatile || right.Type.IsVolatile; // 3. if both operands are constants if (left.IsConstExpr && right.IsConstExpr) { switch (typeKind) { case ABT.ExprTypeKind.DOUBLE: return(new ABT.ConstDouble(OperateDouble(((ABT.ConstDouble)left).Value, ((ABT.ConstDouble)right).Value), env)); case ABT.ExprTypeKind.FLOAT: return(new ABT.ConstFloat(OperateFloat(((ABT.ConstFloat)left).Value, ((ABT.ConstFloat)right).Value), env)); case ABT.ExprTypeKind.ULONG: return(new ABT.ConstULong(OperateULong(((ABT.ConstULong)left).Value, ((ABT.ConstULong)right).Value), env)); case ABT.ExprTypeKind.LONG: return(new ABT.ConstLong(OperateLong(((ABT.ConstLong)left).Value, ((ABT.ConstLong)right).Value), env)); default: throw new InvalidOperationException("Expected arithmetic Type."); } } // 4. if not both operands are constants switch (typeKind) { case ABT.ExprTypeKind.DOUBLE: return(ConstructExpr(left, right, new ABT.DoubleType(isConst, isVolatile))); case ABT.ExprTypeKind.FLOAT: return(ConstructExpr(left, right, new ABT.FloatType(isConst, isVolatile))); case ABT.ExprTypeKind.ULONG: return(ConstructExpr(left, right, new ABT.ULongType(isConst, isVolatile))); case ABT.ExprTypeKind.LONG: return(ConstructExpr(left, right, new ABT.LongType(isConst, isVolatile))); default: throw new InvalidOperationException("Expected arithmetic Type."); } }
public ISemantReturn <ABT.ExprType> DecorateType(ABT.Env env, ABT.ExprType baseType) { var type = this.TypeModifiers .Reverse() // The first Type modifier is nearest to the symbol name, which indicates the outmost Type. .Aggregate( // Wrap up the Type based on the Type modifiers. baseType, (currentType, typeModifier) => Semant(typeModifier.DecorateType, currentType, ref env) ); return(SemantReturn.Create(env, type)); }
public override ABT.Expr GetExpr(ABT.Env env) { //Tuple<AST.Env, AST.ExprType> type_env = this.TypeName.GetTypeEnv(env); //env = type_env.Item1; //AST.ExprType Type = type_env.Item2; var type = Semant(this.TypeName.GetExprType, ref env); return(new ABT.ConstULong((UInt32)type.SizeOf, env)); }
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); 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 ISemantReturn <ABT.ExprType> DecorateType(ABT.Env env, ABT.ExprType returnType) { if (this.ParamTypeList.IsNone) { return(SemantReturn.Create(env, ABT.FunctionType.Create(returnType))); } var paramTypeList = this.ParamTypeList.Value; var namesAndTypes = Semant(paramTypeList.GetNamesAndTypes, ref env); var hasVarArgs = paramTypeList.HasVarArgs; return(SemantReturn.Create(env, ABT.FunctionType.Create(returnType, namesAndTypes, hasVarArgs))); }
public override ABT.Expr GetExpr(ABT.Env env) { switch (this.FloatSuffix) { case TokenFloat.FloatSuffix.F: return(new ABT.ConstFloat((Single)this.Value, env)); case TokenFloat.FloatSuffix.NONE: case TokenFloat.FloatSuffix.L: return(new ABT.ConstDouble(this.Value, env)); default: throw new InvalidOperationException(); } }
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) { switch (this.Suffix) { case TokenInt.IntSuffix.U: case TokenInt.IntSuffix.UL: return(new ABT.ConstULong((UInt32)this.Value, env)); case TokenInt.IntSuffix.NONE: case TokenInt.IntSuffix.L: return(new ABT.ConstLong((Int32)this.Value, env)); default: throw new InvalidOperationException(); } }
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 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) { 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) { var 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) { Boolean isZero; switch (expr.Type.Kind) { case ABT.ExprTypeKind.LONG: isZero = ((ABT.ConstLong)expr).Value == 0; break; case ABT.ExprTypeKind.ULONG: isZero = ((ABT.ConstULong)expr).Value == 0; break; case ABT.ExprTypeKind.FLOAT: isZero = ((ABT.ConstFloat)expr).Value == 0; break; case ABT.ExprTypeKind.DOUBLE: isZero = ((ABT.ConstDouble)expr).Value == 0; break; default: throw new InvalidOperationException(); } return(new ABT.ConstLong(Convert.ToInt32(isZero), env)); } return(new ABT.LogicalNot(expr)); }
public override ABT.Expr GetExpr(ABT.Env env) { // 1. semant the operands var left = SemantExpr(this.Left, ref env); var right = SemantExpr(this.Right, ref env); if (left.Type is ABT.ArrayType) { left = ABT.TypeCast.MakeCast(left, new ABT.PointerType(((ABT.ArrayType)left.Type).ElemType, left.Type.IsConst, left.Type.IsVolatile)); } if (right.Type is ABT.ArrayType) { right = ABT.TypeCast.MakeCast(right, new ABT.PointerType(((ABT.ArrayType)right.Type).ElemType, right.Type.IsConst, right.Type.IsVolatile)); } // 2. ptr + int if (left.Type.Kind == ABT.ExprTypeKind.POINTER) { if (!right.Type.IsIntegral) { throw new InvalidOperationException("Expected integral to be added to a pointer."); } right = ABT.TypeCast.MakeCast(right, new ABT.LongType(right.Type.IsConst, right.Type.IsVolatile)); return(GetPointerAddition(left, right)); } // 3. int + ptr if (right.Type.Kind == ABT.ExprTypeKind.POINTER) { if (!left.Type.IsIntegral) { throw new InvalidOperationException("Expected integral to be added to a pointer."); } left = ABT.TypeCast.MakeCast(left, new ABT.LongType(left.Type.IsConst, left.Type.IsVolatile)); return(GetPointerAddition(right, left, false)); } // 4. usual arithmetic conversion return(base.GetExpr(env)); }
public override ISemantReturn <ABT.ExprType> DecorateType(ABT.Env env, ABT.ExprType elemType) { if (this.NumElems.IsNone) { return(SemantReturn.Create(env, new ABT.IncompleteArrayType(elemType))); } // Get number of elements. // Be careful: the environment might change. var numElems = SemantExpr(this.NumElems.Value, ref env); // Try to cast number of elements to a integer. // TODO: allow float??? numElems = ABT.TypeCast.MakeCast(numElems, new ABT.LongType(true, false)); if (!numElems.IsConstExpr) { throw new InvalidOperationException("Number of elements of an array must be constant."); } return(SemantReturn.Create(env, new ABT.ArrayType(elemType, ((ABT.ConstLong)numElems).Value))); }