本文整理匯總了C#中AST.PushEntry方法的典型用法代碼示例。如果您正苦於以下問題:C# AST.PushEntry方法的具體用法?C# AST.PushEntry怎麽用?C# AST.PushEntry使用的例子?那麽, 這裏精選的方法代碼示例或許可以為您提供幫助。您也可以進一步了解該方法所在類AST
的用法示例。
在下文中一共展示了AST.PushEntry方法的4個代碼示例,這些例子默認根據受歡迎程度排序。您可以為喜歡或者感覺有用的代碼點讚,您的評價將有助於係統推薦出更棒的C#代碼示例。
示例1: GetDeclns
public Tuple<AST.Env, List<Tuple<AST.Env, AST.Decln>>> GetDeclns(AST.Env env) {
// Get storage class, and base type.
Tuple<AST.Env, AST.Decln.SCS, AST.ExprType> r_specs = decln_specs.GetSCSType(env);
env = r_specs.Item1;
AST.Decln.SCS scs = r_specs.Item2;
AST.ExprType base_type = r_specs.Item3;
List<Tuple<AST.Env, AST.Decln>> declns = new List<Tuple<AST.Env, AST.Decln>>();
// For each init declarators, we'll generate a declaration.
foreach (InitDeclr init_declr in init_declrs) {
// Get the final type, name, and initializer.
Tuple<AST.Env, AST.ExprType, Option<AST.Initr>, String> r_declr = init_declr.GetInitDeclr(env, base_type);
env = r_declr.Item1;
AST.ExprType type = r_declr.Item2;
Option<AST.Initr> initr = r_declr.Item3;
String name = r_declr.Item4;
// Insert the new symbol into the environment.
AST.Env.EntryKind kind;
switch (scs) {
case AST.Decln.SCS.AUTO:
if (env.IsGlobal()) {
kind = AST.Env.EntryKind.GLOBAL;
} else {
kind = AST.Env.EntryKind.STACK;
}
break;
case AST.Decln.SCS.EXTERN:
kind = AST.Env.EntryKind.GLOBAL;
break;
case AST.Decln.SCS.STATIC:
kind = AST.Env.EntryKind.GLOBAL;
break;
case AST.Decln.SCS.TYPEDEF:
kind = AST.Env.EntryKind.TYPEDEF;
break;
default:
throw new InvalidOperationException();
}
env = env.PushEntry(kind, name, type);
// Generate the declaration.
declns.Add(Tuple.Create(env, new AST.Decln(name, scs, type, initr)));
}
return new Tuple<AST.Env, List<Tuple<AST.Env, AST.Decln>>>(env, declns);
}
示例2: GetFuncDef
public Tuple<AST.Env, AST.FuncDef> GetFuncDef(AST.Env env)
{
// Get storage class specifier and base type from declaration specifiers.
Tuple<AST.Env, AST.Decln.SCS, AST.ExprType> r_specs = this.specs.GetSCSType(env);
env = r_specs.Item1;
AST.Decln.SCS scs = r_specs.Item2;
AST.ExprType base_type = r_specs.Item3;
// Get function name and function type from declarator.
Tuple<String, AST.ExprType> r_declr = this.declr.GetNameAndType(env, base_type);
String name = r_declr.Item1;
AST.ExprType type = r_declr.Item2;
AST.TFunction func_type;
if (type.kind == AST.ExprType.Kind.FUNCTION) {
func_type = (AST.TFunction)type;
} else {
throw new InvalidOperationException($"{name} is not a function.");
}
switch (scs) {
case AST.Decln.SCS.AUTO:
case AST.Decln.SCS.EXTERN:
case AST.Decln.SCS.STATIC:
env = env.PushEntry(AST.Env.EntryKind.GLOBAL, name, type);
break;
case AST.Decln.SCS.TYPEDEF:
default:
throw new InvalidOperationException("Invalid storage class specifier for function definition.");
}
env = env.SetCurrentFunction(func_type);
Tuple<AST.Env, AST.Stmt> r_stmt = this.stmt.GetStmt(env);
env = r_stmt.Item1;
AST.Stmt stmt = r_stmt.Item2;
env = env.SetCurrentFunction(new AST.TEmptyFunction());
return Tuple.Create(env, new AST.FuncDef(name, scs, func_type, stmt));
}
示例3: GetExprTypeEnv
public Tuple<AST.Env, AST.ExprType> GetExprTypeEnv(Boolean is_struct, AST.Env env, Boolean is_const, Boolean is_volatile) {
if (name == "") {
// If no name is supplied: must be complete.
// struct { ... } or union { ... }
if (declns == null) {
throw new ArgumentNullException("Error: parser should ensure declns != null");
}
Tuple<AST.Env, List<Tuple<String, AST.ExprType>>> r_attribs = GetAttribs(env);
env = r_attribs.Item1;
if (is_struct) {
return new Tuple<AST.Env, AST.ExprType>(env, AST.TStructOrUnion.CreateStruct("<anonymous>", r_attribs.Item2, is_const, is_volatile));
} else {
return new Tuple<AST.Env, AST.ExprType>(env, AST.TStructOrUnion.CreateUnion("<anonymous>", r_attribs.Item2, is_const, is_volatile));
}
} else {
// If a name is supplied, split into 2 cases.
String typename = is_struct ? $"struct {name}" : $"union {name}";
if (declns == null) {
// Case 1: If no attribute list supplied, then we are either
// 1) mentioning an already-existed struct/union
// or 2) creating an incomplete struct/union
Option<AST.Env.Entry> entry_opt = env.Find(typename);
if (entry_opt.IsNone) {
// If the struct/union is not in the current environment,
// then add an incomplete struct/union into the environment
AST.ExprType type =
is_struct
? AST.TStructOrUnion.CreateIncompleteStruct(name, is_const, is_volatile)
: AST.TStructOrUnion.CreateIncompleteUnion(name, is_const, is_volatile);
env = env.PushEntry(AST.Env.EntryKind.TYPEDEF, typename, type);
return Tuple.Create(env, type);
}
if (entry_opt.Value.kind != AST.Env.EntryKind.TYPEDEF) {
throw new InvalidProgramException(typename + " is not a type? This should be my fault.");
}
// If the struct/union is found, return it.
return Tuple.Create(env, entry_opt.Value.type);
} else {
// Case 2: If an attribute list is supplied.
// 1) Make sure there is no complete struct/union in the current environment.
Option<AST.Env.Entry> entry_opt = env.Find(typename);
if (entry_opt.IsSome && entry_opt.Value.type.kind == AST.ExprType.Kind.STRUCT_OR_UNION && ((AST.TStructOrUnion)entry_opt.Value.type).IsComplete) {
throw new InvalidOperationException($"Redefining {typename}");
}
// 2) Add an incomplete struct/union into the environment.
AST.TStructOrUnion type =
is_struct
? AST.TStructOrUnion.CreateIncompleteStruct(name, is_const, is_volatile)
: AST.TStructOrUnion.CreateIncompleteUnion(name, is_const, is_volatile);
env = env.PushEntry(AST.Env.EntryKind.TYPEDEF, typename, type);
// 3) Iterate over the attributes.
Tuple<AST.Env, List<Tuple<String, AST.ExprType>>> r_attribs = GetAttribs(env);
env = r_attribs.Item1;
// 4) Make the type complete. This would also change the entry inside env.
if (is_struct) {
type.DefineStruct(r_attribs.Item2);
} else {
type.DefineUnion(r_attribs.Item2);
}
return new Tuple<AST.Env, AST.ExprType>(env, type);
}
}
}
示例4: GetExpr
public override AST.Expr GetExpr(AST.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(
loc: AST.Env.EntryKind.TYPEDEF,
name: (this.func as Variable).name,
type: AST.TFunction.Create(
ret_type: new AST.TLong(is_const: true),
args: args.ConvertAll(_ => Tuple.Create("", _.type)),
is_varargs: false
)
);
}
// Step 2: get function expression.
AST.Expr func = this.func.GetExpr(env);
// Step 3: get the function type.
AST.TFunction func_type;
switch (func.type.kind) {
case AST.ExprType.Kind.FUNCTION:
func_type = func.type as AST.TFunction;
break;
case AST.ExprType.Kind.POINTER:
var ref_t = (func.type as AST.TPointer).ref_t;
if (!(ref_t is AST.TFunction)) {
throw new InvalidOperationException("Expected a function pointer.");
}
func_type = ref_t as AST.TFunction;
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.is_varargs && 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 = Enumerable.Zip(
args.GetRange(0, num_args_prototype),
func_type.args,
(arg, entry) => AST.TypeCast.MakeCast(arg, entry.type)
).Concat(args.GetRange(num_args_prototype, num_args_actual - num_args_prototype)).ToList();
return new AST.FuncCall(func, func_type, args);
}