1457 lines
61 KiB
C#
1457 lines
61 KiB
C#
|
using System;
|
||
|
using System.IO;
|
||
|
using System.Compiler;
|
||
|
|
||
|
public class cci {
|
||
|
public static object visit(object ast, TextWriter w, string[] args, MessageWriter msg) {
|
||
|
if (msg.Count == 0)
|
||
|
return new cci(w, msg).compilation((compilation)ast);
|
||
|
return null;
|
||
|
}
|
||
|
protected Document document;
|
||
|
protected MessageWriter msg;
|
||
|
protected TextWriter w;
|
||
|
|
||
|
public cci(TextWriter w, MessageWriter msg) {
|
||
|
this.w = w;
|
||
|
this.msg = msg;
|
||
|
}
|
||
|
|
||
|
Node accessor_declaration(accessor_declaration ast) {
|
||
|
foreach (attribute_section x in ast.attrs)
|
||
|
attribute_section(x);
|
||
|
if (ast.body != null)
|
||
|
statement(ast.body);
|
||
|
// InputElement ast.id
|
||
|
// [Bind1] Method ast.sym
|
||
|
// [Emit] MethodBuilder ast.builder
|
||
|
// InputElementList ast.mods
|
||
|
return null;
|
||
|
}
|
||
|
Node alias_directive(alias_directive ast) {
|
||
|
// InputElement ast.id
|
||
|
dotted_name(ast.name);
|
||
|
// [Bind1] Symbol ast.sym
|
||
|
return null;
|
||
|
}
|
||
|
Expression anonymous_method_expression(anonymous_method_expression ast) {
|
||
|
foreach (parameter x in ast.formals)
|
||
|
parameter(x);
|
||
|
statement(ast.block);
|
||
|
// Boolean ast.valueUsed
|
||
|
// [Typecheck] Type ast.typ
|
||
|
// [MayBeNull,Typecheck] Object ast.value
|
||
|
return null;
|
||
|
}
|
||
|
Parameter arglist_parameter(arglist_parameter ast) {
|
||
|
Parameter result = new Parameter();
|
||
|
foreach (attribute_section x in ast.attrs)
|
||
|
attribute_section(x);
|
||
|
return result;
|
||
|
}
|
||
|
Expression argument(argument ast) {
|
||
|
return expression(ast.expr);
|
||
|
}
|
||
|
Expression array_creation_expression1(array_creation_expression1 ast) {
|
||
|
foreach (expression x in ast.exprs)
|
||
|
expression(x);
|
||
|
if (ast.init != null)
|
||
|
array_initializer(ast.init);
|
||
|
// intList ast.ranks
|
||
|
type(ast.ty);
|
||
|
// Boolean ast.valueUsed
|
||
|
// [Typecheck] Type ast.typ
|
||
|
// [MayBeNull,Typecheck] Object ast.value
|
||
|
return null;
|
||
|
}
|
||
|
Expression array_creation_expression2(array_creation_expression2 ast) {
|
||
|
array_initializer(ast.init);
|
||
|
type(ast.ty);
|
||
|
// Boolean ast.valueUsed
|
||
|
// [Typecheck] Type ast.typ
|
||
|
// [MayBeNull,Typecheck] Object ast.value
|
||
|
return null;
|
||
|
}
|
||
|
Expression array_initializer(array_initializer ast) {
|
||
|
ConstructArray result = new ConstructArray();
|
||
|
result.Initializers = new ExpressionList();
|
||
|
foreach (variable_initializer x in ast.a)
|
||
|
result.Initializers.Add(variable_initializer(x));
|
||
|
return result;
|
||
|
}
|
||
|
TypeNode array_type(array_type ast) {
|
||
|
// Int32 ast.rank_specifier
|
||
|
type(ast.ty);
|
||
|
// [Bind2] Type ast.sym
|
||
|
return null;
|
||
|
}
|
||
|
Expression as_expression(as_expression ast) {
|
||
|
return new BinaryExpression(expression(ast.expr),
|
||
|
new MemberBinding(null, type(ast.ty)), NodeType.As);
|
||
|
}
|
||
|
Expression assignment_expression(assignment_expression ast) {
|
||
|
return new AssignmentExpression(
|
||
|
new AssignmentStatement(expression(ast.e1), expression(ast.e2)));
|
||
|
}
|
||
|
Node attribute(attribute ast) {
|
||
|
if (ast.arguments != null)
|
||
|
attribute_arguments(ast.arguments);
|
||
|
type(ast.name);
|
||
|
return null;
|
||
|
}
|
||
|
Node attribute_arguments(attribute_arguments ast) {
|
||
|
foreach (expression x in ast.args)
|
||
|
expression(x);
|
||
|
foreach (named_argument x in ast.namedargs)
|
||
|
named_argument(x);
|
||
|
return null;
|
||
|
}
|
||
|
Node attribute_section(attribute_section ast) {
|
||
|
foreach (attribute x in ast.attributes)
|
||
|
attribute(x);
|
||
|
// [MayBeNull] InputElement ast.target
|
||
|
return null;
|
||
|
}
|
||
|
Expression base_access(base_access ast) {
|
||
|
return new Base();
|
||
|
}
|
||
|
Node base_initializer(base_initializer ast) {
|
||
|
foreach (argument x in ast.args)
|
||
|
argument(x);
|
||
|
// [Typecheck] Constructor ast.method
|
||
|
return null;
|
||
|
}
|
||
|
Node binary_declarator(binary_declarator ast) {
|
||
|
// InputElement ast.id1
|
||
|
// InputElement ast.id2
|
||
|
// InputElement ast.op
|
||
|
type(ast.t1);
|
||
|
type(ast.t2);
|
||
|
// [Bind1] Formal ast.sym1
|
||
|
// [Bind1] Formal ast.sym2
|
||
|
type(ast.ty);
|
||
|
// [Bind1] Method ast.method
|
||
|
return null;
|
||
|
}
|
||
|
Expression binary_expression(binary_expression ast) {
|
||
|
NodeType op;
|
||
|
switch (ast.op.str) {
|
||
|
case "+": op = NodeType.Add; break;
|
||
|
case "&": op = NodeType.And; break;
|
||
|
case "|": op = NodeType.Or; break;
|
||
|
case "^": op = NodeType.Xor; break;
|
||
|
case "/": op = NodeType.Div; break;
|
||
|
case "=": op = NodeType.Eq; break;
|
||
|
case ">": op = NodeType.Gt; break;
|
||
|
case ">=": op = NodeType.Ge; break;
|
||
|
case "<<": op = NodeType.Shl; break;
|
||
|
case "<": op = NodeType.Lt; break;
|
||
|
case "<=": op = NodeType.Le; break;
|
||
|
case "&&": op = NodeType.LogicalAnd; break;
|
||
|
case "||": op = NodeType.LogicalOr; break;
|
||
|
case "*": op = NodeType.Mul; break;
|
||
|
case "!=": op = NodeType.Ne; break;
|
||
|
case "%": op = NodeType.Rem; break;
|
||
|
case ">>": op = NodeType.Shr; break;
|
||
|
case "-": op = NodeType.Sub; break;
|
||
|
default: op = NodeType.Nop; break;
|
||
|
}
|
||
|
return new BinaryExpression(expression(ast.e1), expression(ast.e2), op);
|
||
|
}
|
||
|
System.Compiler.Block block(statement ast) {
|
||
|
if (ast is block_statement)
|
||
|
return (System.Compiler.Block)statement(ast);
|
||
|
else
|
||
|
return new System.Compiler.Block(new StatementList(statement(ast)), context(ast));
|
||
|
}
|
||
|
Statement block_statement(block_statement ast) {
|
||
|
StatementList stmts = new StatementList();
|
||
|
foreach (statement x in ast.stmts)
|
||
|
stmts.Add(statement(x));
|
||
|
return new System.Compiler.Block(stmts, context(ast));
|
||
|
}
|
||
|
TypeNode bool_type(bool_type ast) {
|
||
|
return SystemTypes.Boolean;
|
||
|
}
|
||
|
Expression boolean_literal(boolean_literal ast) {
|
||
|
return new Literal(ast.token.str == "true", SystemTypes.Boolean);
|
||
|
}
|
||
|
Statement break_statement(break_statement ast) {
|
||
|
return new Exit();
|
||
|
}
|
||
|
TypeNode byte_type(byte_type ast) {
|
||
|
return SystemTypes.UInt8;
|
||
|
}
|
||
|
Expression cast_expression(cast_expression ast) {
|
||
|
return new BinaryExpression(expression(ast.expr),
|
||
|
new MemberBinding(null, typeexpression(ast.ty)), NodeType.Castclass);
|
||
|
}
|
||
|
Catch catch_clause(catch_clause ast) {
|
||
|
Catch result = new Catch();
|
||
|
result.Type = type(ast.ty);
|
||
|
if (ast.id != null)
|
||
|
result.Variable = identifier(ast.id);
|
||
|
result.Block = block(ast.block);
|
||
|
return result;
|
||
|
}
|
||
|
CatchList catch_clauses(catch_clauses ast) {
|
||
|
CatchList catches = new CatchList();
|
||
|
if (ast.general != null)
|
||
|
catches.Add(new Catch(block(ast.general), null, null));
|
||
|
foreach (catch_clause x in ast.specifics)
|
||
|
catches.Add(catch_clause(x));
|
||
|
return catches;
|
||
|
}
|
||
|
TypeNode char_type(char_type ast) {
|
||
|
return SystemTypes.Char;
|
||
|
}
|
||
|
Expression character_literal(character_literal ast) {
|
||
|
bool errorFlag;
|
||
|
return new Literal(typecheck.characterLiteral(ast.token.str, out errorFlag), SystemTypes.Char);
|
||
|
}
|
||
|
Expression checked_expression(checked_expression ast) {
|
||
|
BlockExpression result = new BlockExpression();
|
||
|
result.Block = new System.Compiler.Block(new StatementList(expressionstatement(ast.expr)), true, false);
|
||
|
return result;
|
||
|
}
|
||
|
Statement checked_statement(checked_statement ast) {
|
||
|
System.Compiler.Block result = block(ast.stmt);
|
||
|
result.Checked = true;
|
||
|
result.SuppressCheck = false;
|
||
|
return result;
|
||
|
}
|
||
|
Node class_declaration(class_declaration ast) {
|
||
|
System.Compiler.Class result = new System.Compiler.Class();
|
||
|
result.Name = identifier(ast.id);
|
||
|
foreach (attribute_section x in ast.attrs)
|
||
|
attribute_section(x);
|
||
|
result.Flags = getTypeFlags(stringList(ast.mods), ast.parent is type_declaration);
|
||
|
foreach (type_parameter x in ast.typeparams)
|
||
|
type_parameter(x);
|
||
|
foreach (type x in ast.bases)
|
||
|
type(x);
|
||
|
foreach (type_parameter_constraints_clause x in ast.constraints)
|
||
|
type_parameter_constraints_clause(x);
|
||
|
result.Members = new MemberList();
|
||
|
foreach (declaration x in ast.body) {
|
||
|
Object d = declaration(x);
|
||
|
if (d is Member)
|
||
|
result.Members.Add((Member)d);
|
||
|
else if (d is MemberList) {
|
||
|
MemberList m = (MemberList)d;
|
||
|
for (int i = 0; i < m.Length; i++)
|
||
|
result.Members.Add(m[i]);
|
||
|
}
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
object compilation(compilation ast) {
|
||
|
Compilation result = new Compilation();
|
||
|
result.CompilationUnits = new CompilationUnitList();
|
||
|
foreach (compilation_unit x in ast.inputs)
|
||
|
result.CompilationUnits.Add(compilation_unit(x));
|
||
|
return result;
|
||
|
}
|
||
|
CompilationUnit compilation_unit(compilation_unit ast) {
|
||
|
CompilationUnit result = new CompilationUnit();
|
||
|
result.Nodes = new NodeList();
|
||
|
document = new Document();
|
||
|
if (ast.begin.file != null) {
|
||
|
try {
|
||
|
StreamReader r = new StreamReader(ast.begin.file);
|
||
|
document.Text = new DocumentText(r.ReadToEnd());
|
||
|
r.Close();
|
||
|
} catch (Exception) {
|
||
|
document.Text = new DocumentText(source.ToString(ast));
|
||
|
}
|
||
|
} else
|
||
|
document.Text = new DocumentText(source.ToString(ast));
|
||
|
result.SourceContext = context(ast);
|
||
|
foreach (attribute_section x in ast.attributes)
|
||
|
attribute_section(x);
|
||
|
foreach (using_directive x in ast.using_directives)
|
||
|
using_directive(x);
|
||
|
foreach (declaration x in ast.declarations)
|
||
|
result.Nodes.Add((Node)declaration(x));
|
||
|
return result;
|
||
|
}
|
||
|
Expression compound_assignment_expression(compound_assignment_expression ast) {
|
||
|
NodeType op;
|
||
|
switch (ast.op.str) {
|
||
|
case "+=": op = NodeType.Add; break;
|
||
|
case "&=": op = NodeType.And; break;
|
||
|
case "|=": op = NodeType.Or; break;
|
||
|
case "^=": op = NodeType.Xor; break;
|
||
|
case "/=": op = NodeType.Div; break;
|
||
|
case "<<=": op = NodeType.Shl; break;
|
||
|
case "*=": op = NodeType.Mul; break;
|
||
|
case "!=": op = NodeType.Ne; break;
|
||
|
case "%=": op = NodeType.Rem; break;
|
||
|
case ">>=": op = NodeType.Shr; break;
|
||
|
case "-=": op = NodeType.Sub; break;
|
||
|
default: op = NodeType.Nop; break;
|
||
|
}
|
||
|
return new AssignmentExpression(
|
||
|
new AssignmentStatement(expression(ast.e1), expression(ast.e2), op));
|
||
|
}
|
||
|
Expression cond_expression(cond_expression ast) {
|
||
|
return new TernaryExpression(expression(ast.cond),
|
||
|
expression(ast.success), expression(ast.failure), NodeType.Conditional, null);
|
||
|
}
|
||
|
LocalDeclaration const_declarator(const_declarator ast) {
|
||
|
return new LocalDeclaration(identifier(ast.id), expression(ast.expr));
|
||
|
}
|
||
|
Statement const_statement(const_statement ast) {
|
||
|
LocalDeclarationsStatement result = new LocalDeclarationsStatement();
|
||
|
result.Constant = true;
|
||
|
result.Type = type(ast.ty);
|
||
|
result.Declarations = new LocalDeclarationList();
|
||
|
foreach (const_declarator x in ast.consts)
|
||
|
result.Declarations.Add(const_declarator(x));
|
||
|
return result;
|
||
|
}
|
||
|
Node constant_declaration(constant_declaration ast) {
|
||
|
foreach (attribute_section x in ast.attrs)
|
||
|
attribute_section(x);
|
||
|
foreach (declarator x in ast.decls)
|
||
|
declarator(x);
|
||
|
type(ast.ty);
|
||
|
// InputElementList ast.mods
|
||
|
return null;
|
||
|
}
|
||
|
TypeNode constructor_constraint(constructor_constraint ast) {
|
||
|
// [Bind2] Type ast.sym
|
||
|
return null;
|
||
|
}
|
||
|
Node constructor_declaration(constructor_declaration ast) {
|
||
|
foreach (attribute_section x in ast.attrs)
|
||
|
attribute_section(x);
|
||
|
if (ast.block != null)
|
||
|
statement(ast.block);
|
||
|
constructor_declarator(ast.decl);
|
||
|
// [Bind1] Constructor ast.sym
|
||
|
// [Emit] ConstructorBuilder ast.builder
|
||
|
// InputElementList ast.mods
|
||
|
return null;
|
||
|
}
|
||
|
Node constructor_declarator(constructor_declarator ast) {
|
||
|
formals(ast.f);
|
||
|
// InputElement ast.id
|
||
|
if (ast.init != null)
|
||
|
constructor_initializer(ast.init);
|
||
|
return null;
|
||
|
}
|
||
|
Node constructor_initializer(constructor_initializer ast) {
|
||
|
if (ast is base_initializer) return base_initializer((base_initializer)ast);
|
||
|
else if (ast is this_initializer) return this_initializer((this_initializer)ast);
|
||
|
else throw new ArgumentException();
|
||
|
}
|
||
|
SourceContext context(AST ast) {
|
||
|
return context(ast.begin, ast.end);
|
||
|
}
|
||
|
SourceContext context(Coordinate begin, Coordinate end) {
|
||
|
Debug.Assert(document != null);
|
||
|
return new SourceContext(document, begin.line - 1, begin.column - 1 , end.line - 1, end.column - 1);
|
||
|
}
|
||
|
Statement continue_statement(continue_statement ast) {
|
||
|
return new Continue();
|
||
|
}
|
||
|
TypeNode decimal_type(decimal_type ast) {
|
||
|
return SystemTypes.Decimal;
|
||
|
}
|
||
|
object declaration(declaration ast) {
|
||
|
object result = null;
|
||
|
if (ast is accessor_declaration) result = accessor_declaration((accessor_declaration)ast);
|
||
|
else if (ast is type_declaration) result = type_declaration((type_declaration)ast);
|
||
|
else if (ast is constant_declaration) result = constant_declaration((constant_declaration)ast);
|
||
|
else if (ast is constructor_declaration) result = constructor_declaration((constructor_declaration)ast);
|
||
|
else if (ast is destructor_declaration) result = destructor_declaration((destructor_declaration)ast);
|
||
|
else if (ast is event_declaration1) result = event_declaration1((event_declaration1)ast);
|
||
|
else if (ast is event_declaration2) result = event_declaration2((event_declaration2)ast);
|
||
|
else if (ast is field_declaration) result = field_declaration((field_declaration)ast);
|
||
|
else if (ast is interface_method_declaration) result = interface_method_declaration((interface_method_declaration)ast);
|
||
|
else if (ast is method_declaration) result = method_declaration((method_declaration)ast);
|
||
|
else if (ast is indexer_declaration) result = indexer_declaration((indexer_declaration)ast);
|
||
|
else if (ast is interface_event_declaration) result = interface_event_declaration((interface_event_declaration)ast);
|
||
|
else if (ast is interface_indexer_declaration) result = interface_indexer_declaration((interface_indexer_declaration)ast);
|
||
|
else if (ast is interface_property_declaration) result = interface_property_declaration((interface_property_declaration)ast);
|
||
|
else if (ast is namespace_declaration) result = namespace_declaration((namespace_declaration)ast);
|
||
|
else if (ast is operator_declaration) result = operator_declaration((operator_declaration)ast);
|
||
|
else if (ast is property_declaration) result = property_declaration((property_declaration)ast);
|
||
|
else throw new ArgumentException();
|
||
|
if (result is Member)
|
||
|
((Member)result).SourceContext = context(ast);
|
||
|
return result;
|
||
|
}
|
||
|
Node declarator(declarator ast) {
|
||
|
if (ast is const_declarator) return const_declarator((const_declarator)ast);
|
||
|
else if (ast is event_declarator) return event_declarator((event_declarator)ast);
|
||
|
else if (ast is field_declarator) return field_declarator((field_declarator)ast);
|
||
|
else if (ast is fixed_declarator) return fixed_declarator((fixed_declarator)ast);
|
||
|
else if (ast is var_declarator) return var_declarator((var_declarator)ast);
|
||
|
else throw new ArgumentException();
|
||
|
}
|
||
|
Node delegate_declaration(delegate_declaration ast) {
|
||
|
foreach (attribute_section x in ast.attrs)
|
||
|
attribute_section(x);
|
||
|
foreach (type_parameter x in ast.typeparams)
|
||
|
type_parameter(x);
|
||
|
foreach (type_parameter_constraints_clause x in ast.constraints)
|
||
|
type_parameter_constraints_clause(x);
|
||
|
formals(ast.f);
|
||
|
// InputElement ast.id
|
||
|
type(ast.ty);
|
||
|
// [Bind1] DelegateType ast.sym
|
||
|
// [Emit] Type ast.type
|
||
|
// InputElementList ast.mods
|
||
|
return null;
|
||
|
}
|
||
|
Node destructor_declaration(destructor_declaration ast) {
|
||
|
foreach (attribute_section x in ast.attrs)
|
||
|
attribute_section(x);
|
||
|
if (ast.block != null)
|
||
|
statement(ast.block);
|
||
|
// InputElement ast.id
|
||
|
// [Bind1] Method ast.sym
|
||
|
// [Emit] MethodBuilder ast.builder
|
||
|
// InputElementList ast.mods
|
||
|
return null;
|
||
|
}
|
||
|
Statement do_statement(do_statement ast) {
|
||
|
return new DoWhile(expression(ast.expr), block(ast.body));
|
||
|
}
|
||
|
Expression dotted_name(dotted_name ast) {
|
||
|
Expression result;
|
||
|
if (ast.left != null)
|
||
|
result = new QualifiedIdentifier(dotted_name(ast.left), identifier(ast.right));
|
||
|
else
|
||
|
result = identifier(ast.right);
|
||
|
if (ast.typeargs != null) {
|
||
|
foreach (type x in ast.typeargs)
|
||
|
type(x);
|
||
|
}
|
||
|
result.SourceContext = context(ast);
|
||
|
return result;
|
||
|
}
|
||
|
TypeNode double_type(double_type ast) {
|
||
|
return SystemTypes.Double;
|
||
|
}
|
||
|
Expression element_access(element_access ast) {
|
||
|
ExpressionList args = new ExpressionList();
|
||
|
foreach (argument x in ast.exprs)
|
||
|
args.Add(argument(x));
|
||
|
return new Indexer(expression(ast.expr), args);
|
||
|
}
|
||
|
Statement empty_statement(empty_statement ast) {
|
||
|
return new System.Compiler.Block();
|
||
|
}
|
||
|
Node enum_declaration(enum_declaration ast) {
|
||
|
foreach (attribute_section x in ast.attrs)
|
||
|
attribute_section(x);
|
||
|
foreach (enum_member_declaration x in ast.body)
|
||
|
enum_member_declaration(x);
|
||
|
// InputElement ast.id
|
||
|
if (ast.ty != null)
|
||
|
type(ast.ty);
|
||
|
// [Bind1] EnumType ast.sym
|
||
|
// [Emit] Type ast.type
|
||
|
// InputElementList ast.mods
|
||
|
return null;
|
||
|
}
|
||
|
Node enum_member_declaration(enum_member_declaration ast) {
|
||
|
foreach (attribute_section x in ast.attrs)
|
||
|
attribute_section(x);
|
||
|
if (ast.expr != null)
|
||
|
expression(ast.expr);
|
||
|
// InputElement ast.id
|
||
|
// [Bind1] EnumMember ast.sym
|
||
|
// [Emit] FieldBuilder ast.builder
|
||
|
return null;
|
||
|
}
|
||
|
Node event_accessor(event_accessor ast) {
|
||
|
foreach (attribute_section x in ast.attrs)
|
||
|
attribute_section(x);
|
||
|
statement(ast.block);
|
||
|
// InputElement ast.id
|
||
|
// [Bind1] Method ast.sym
|
||
|
// [Emit] MethodBuilder ast.builder
|
||
|
return null;
|
||
|
}
|
||
|
Node event_declaration1(event_declaration1 ast) {
|
||
|
foreach (attribute_section x in ast.attrs)
|
||
|
attribute_section(x);
|
||
|
foreach (declarator x in ast.decls)
|
||
|
declarator(x);
|
||
|
type(ast.ty);
|
||
|
// InputElementList ast.mods
|
||
|
return null;
|
||
|
}
|
||
|
Node event_declaration2(event_declaration2 ast) {
|
||
|
foreach (event_accessor x in ast.accessors)
|
||
|
event_accessor(x);
|
||
|
foreach (attribute_section x in ast.attrs)
|
||
|
attribute_section(x);
|
||
|
member_name(ast.name);
|
||
|
type(ast.ty);
|
||
|
// [Bind1] Event ast.sym
|
||
|
// [Emit] EventBuilder ast.builder
|
||
|
// InputElementList ast.mods
|
||
|
return null;
|
||
|
}
|
||
|
Node event_declarator(event_declarator ast) {
|
||
|
if (ast.init != null)
|
||
|
variable_initializer(ast.init);
|
||
|
// [Bind1] Event ast.sym
|
||
|
// [Emit] FieldBuilder ast.builder
|
||
|
// [Emit] EventBuilder ast.event_builder
|
||
|
// [Emit] MethodBuilder ast.add_builder
|
||
|
// [Emit] MethodBuilder ast.remove_builder
|
||
|
// InputElement ast.id
|
||
|
return null;
|
||
|
}
|
||
|
Node explicit_declarator(explicit_declarator ast) {
|
||
|
// InputElement ast.id1
|
||
|
type(ast.t1);
|
||
|
// [Bind1] Formal ast.sym
|
||
|
type(ast.ty);
|
||
|
// [Bind1] Method ast.method
|
||
|
return null;
|
||
|
}
|
||
|
Expression expr_access(expr_access ast) {
|
||
|
Expression result = new QualifiedIdentifier(expression(ast.expr), identifier(ast.id));
|
||
|
if (ast.typeargs != null) {
|
||
|
foreach (type x in ast.typeargs)
|
||
|
type(x);
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
Expression expr_initializer(expr_initializer ast) {
|
||
|
return expression(ast.expr);
|
||
|
}
|
||
|
Expression expression(expression ast) {
|
||
|
Expression result = null;
|
||
|
if (ast is anonymous_method_expression) result = anonymous_method_expression((anonymous_method_expression)ast);
|
||
|
else if (ast is array_creation_expression1) result = array_creation_expression1((array_creation_expression1)ast);
|
||
|
else if (ast is array_creation_expression2) result = array_creation_expression2((array_creation_expression2)ast);
|
||
|
else if (ast is as_expression) result = as_expression((as_expression)ast);
|
||
|
else if (ast is assignment_expression) result = assignment_expression((assignment_expression)ast);
|
||
|
else if (ast is base_access) result = base_access((base_access)ast);
|
||
|
else if (ast is binary_expression) result = binary_expression((binary_expression)ast);
|
||
|
else if (ast is literal) result = literal((literal)ast);
|
||
|
else if (ast is cast_expression) result = cast_expression((cast_expression)ast);
|
||
|
else if (ast is checked_expression) result = checked_expression((checked_expression)ast);
|
||
|
else if (ast is compound_assignment_expression) result = compound_assignment_expression((compound_assignment_expression)ast);
|
||
|
else if (ast is cond_expression) result = cond_expression((cond_expression)ast);
|
||
|
else if (ast is element_access) result = element_access((element_access)ast);
|
||
|
else if (ast is member_access) result = member_access((member_access)ast);
|
||
|
else if (ast is implicit_cast_expression) result = implicit_cast_expression((implicit_cast_expression)ast);
|
||
|
else if (ast is invocation_expression) result = invocation_expression((invocation_expression)ast);
|
||
|
else if (ast is is_expression) result = is_expression((is_expression)ast);
|
||
|
else if (ast is new_expression) result = new_expression((new_expression)ast);
|
||
|
else if (ast is post_expression) result = post_expression((post_expression)ast);
|
||
|
else if (ast is pre_expression) result = pre_expression((pre_expression)ast);
|
||
|
else if (ast is simple_name) result = simple_name((simple_name)ast);
|
||
|
else if (ast is sizeof_expression) result = sizeof_expression((sizeof_expression)ast);
|
||
|
else if (ast is this_access) result = this_access((this_access)ast);
|
||
|
else if (ast is typeof_expression) result = typeof_expression((typeof_expression)ast);
|
||
|
else if (ast is unary_expression) result = unary_expression((unary_expression)ast);
|
||
|
else if (ast is unchecked_expression) result = unchecked_expression((unchecked_expression)ast);
|
||
|
else throw new ArgumentException();
|
||
|
result.SourceContext = context(ast);
|
||
|
return result;
|
||
|
}
|
||
|
Statement expression_statement(expression_statement ast) {
|
||
|
return expressionstatement(ast.expr);
|
||
|
}
|
||
|
ExpressionStatement expressionstatement(expression ast) {
|
||
|
return new ExpressionStatement(expression(ast));
|
||
|
}
|
||
|
MemberList field_declaration(field_declaration ast) {
|
||
|
MemberList result = new MemberList();
|
||
|
foreach (attribute_section x in ast.attrs)
|
||
|
attribute_section(x);
|
||
|
FieldFlags flags = getFieldFlags(stringList(ast.mods));
|
||
|
foreach (field_declarator x in ast.decls) {
|
||
|
System.Compiler.Field f = field_declarator(x);
|
||
|
f.Type = type(ast.ty);
|
||
|
f.Flags = flags;
|
||
|
f.SourceContext = context(x);
|
||
|
result.Add(f);
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
System.Compiler.Field field_declarator(field_declarator ast) {
|
||
|
System.Compiler.Field result = new System.Compiler.Field(identifier(ast.id));
|
||
|
if (ast.init != null)
|
||
|
result.Initializer = variable_initializer(ast.init);
|
||
|
return result;
|
||
|
}
|
||
|
Finally finally_clause(finally_clause ast) {
|
||
|
return new Finally(block(ast.block));
|
||
|
}
|
||
|
Node fixed_declarator(fixed_declarator ast) {
|
||
|
expression(ast.expr);
|
||
|
// [Bind1] Local ast.sym
|
||
|
// InputElement ast.id
|
||
|
return null;
|
||
|
}
|
||
|
Parameter fixed_parameter(fixed_parameter ast) {
|
||
|
Parameter result = new Parameter(identifier(ast.id), type(ast.ty));
|
||
|
if (ast.mod != null)
|
||
|
result.Flags = ParameterFlags.Out;
|
||
|
foreach (attribute_section x in ast.attrs)
|
||
|
attribute_section(x);
|
||
|
return result;
|
||
|
}
|
||
|
Statement fixed_statement(fixed_statement ast) {
|
||
|
Fixed result = new Fixed();
|
||
|
foreach (fixed_declarator x in ast.declarators)
|
||
|
fixed_declarator(x);
|
||
|
type(ast.ty);
|
||
|
result.Body = block(ast.body);
|
||
|
return result;
|
||
|
}
|
||
|
TypeNode float_type(float_type ast) {
|
||
|
return SystemTypes.Single;
|
||
|
}
|
||
|
StatementList for_decl(for_decl ast) {
|
||
|
return new StatementList(local_statement(ast.decl));
|
||
|
}
|
||
|
StatementList for_init(for_init ast) {
|
||
|
if (ast is for_decl) return for_decl((for_decl)ast);
|
||
|
else if (ast is for_list) return for_list((for_list)ast);
|
||
|
else throw new ArgumentException();
|
||
|
}
|
||
|
StatementList for_list(for_list ast) {
|
||
|
StatementList result = new StatementList();
|
||
|
foreach (expression x in ast.exprs)
|
||
|
result.Add(expressionstatement(x));
|
||
|
return result;
|
||
|
}
|
||
|
Statement for_statement(for_statement ast) {
|
||
|
For result = new For();
|
||
|
if (ast.init != null)
|
||
|
result.Initializer = for_init(ast.init);
|
||
|
if (ast.cond != null)
|
||
|
result.Condition = expression(ast.cond);
|
||
|
result.Incrementer = new StatementList();
|
||
|
foreach (expression x in ast.iterators)
|
||
|
result.Incrementer.Add(expressionstatement(x));
|
||
|
result.Body = block(ast.body);
|
||
|
return result;
|
||
|
}
|
||
|
Statement foreach_statement(foreach_statement ast) {
|
||
|
ForEach result = new ForEach();
|
||
|
result.TargetVariableType = type(ast.ty);
|
||
|
result.TargetVariable = identifier(ast.id);
|
||
|
result.SourceEnumerable = expression(ast.expr);
|
||
|
result.Body = block(ast.body);
|
||
|
return null;
|
||
|
}
|
||
|
ParameterList formals(formals ast) {
|
||
|
ParameterList result = new ParameterList();
|
||
|
foreach (parameter x in ast.fixeds)
|
||
|
result.Add(parameter(x));
|
||
|
if (ast.param != null)
|
||
|
parameter(ast.param);
|
||
|
return result;
|
||
|
}
|
||
|
Node generic_interface_method_declaration(generic_interface_method_declaration ast) {
|
||
|
foreach (type_parameter x in ast.typeparams)
|
||
|
type_parameter(x);
|
||
|
foreach (type_parameter_constraints_clause x in ast.constraints)
|
||
|
type_parameter_constraints_clause(x);
|
||
|
foreach (attribute_section x in ast.attrs)
|
||
|
attribute_section(x);
|
||
|
formals(ast.f);
|
||
|
// InputElement ast.id
|
||
|
type(ast.ty);
|
||
|
// [Bind1] Method ast.sym
|
||
|
// [Emit] MethodBuilder ast.builder
|
||
|
// InputElementList ast.mods
|
||
|
return null;
|
||
|
}
|
||
|
Node generic_method_declaration(generic_method_declaration ast) {
|
||
|
foreach (type_parameter x in ast.typeparams)
|
||
|
type_parameter(x);
|
||
|
foreach (type_parameter_constraints_clause x in ast.constraints)
|
||
|
type_parameter_constraints_clause(x);
|
||
|
foreach (attribute_section x in ast.attrs)
|
||
|
attribute_section(x);
|
||
|
if (ast.body != null)
|
||
|
statement(ast.body);
|
||
|
member_name(ast.name);
|
||
|
formals(ast.parms);
|
||
|
type(ast.ty);
|
||
|
// [Bind1] Method ast.sym
|
||
|
// [Emit] MethodBuilder ast.builder
|
||
|
// InputElementList ast.mods
|
||
|
return null;
|
||
|
}
|
||
|
FieldFlags getFieldFlags(stringList modifiers) {
|
||
|
FieldFlags flags = 0;
|
||
|
foreach (string mod in modifiers)
|
||
|
switch (mod) {
|
||
|
case "private": flags |= FieldFlags.Private; break;
|
||
|
case "public": flags |= FieldFlags.Public; break;
|
||
|
case "protected":
|
||
|
if (modifiers.Contains("internal"))
|
||
|
flags |= FieldFlags.FamORAssem;
|
||
|
else
|
||
|
flags |= FieldFlags.Family;
|
||
|
break;
|
||
|
case "internal":
|
||
|
if (modifiers.Contains("protected"))
|
||
|
flags |= FieldFlags.FamORAssem;
|
||
|
else
|
||
|
flags |= FieldFlags.Assembly;
|
||
|
break;
|
||
|
case "static": flags |= FieldFlags.Static; break;
|
||
|
}
|
||
|
return flags;
|
||
|
}
|
||
|
MethodFlags getMethodFlags(stringList modifiers) {
|
||
|
MethodFlags flags = 0;
|
||
|
foreach (string mod in modifiers)
|
||
|
switch (mod) {
|
||
|
case "private": flags |= MethodFlags.Private; break;
|
||
|
case "public": flags |= MethodFlags.Public; break;
|
||
|
case "protected":
|
||
|
if (modifiers.Contains("internal"))
|
||
|
flags |= MethodFlags.FamORAssem;
|
||
|
else
|
||
|
flags |= MethodFlags.Family;
|
||
|
break;
|
||
|
case "internal":
|
||
|
if (modifiers.Contains("protected"))
|
||
|
flags |= MethodFlags.FamORAssem;
|
||
|
else
|
||
|
flags |= MethodFlags.Assembly;
|
||
|
break;
|
||
|
case "static": flags |= MethodFlags.Static; break;
|
||
|
case "override":
|
||
|
case "virtual": flags |= MethodFlags.Virtual; break;
|
||
|
case "new": flags |= MethodFlags.NewSlot; break;
|
||
|
case "abstract": flags |= MethodFlags.Abstract; break;
|
||
|
case "sealed": flags |= MethodFlags.Final; break;
|
||
|
}
|
||
|
return flags;
|
||
|
}
|
||
|
public TypeFlags getTypeFlags(stringList modifiers, bool nested) {
|
||
|
TypeFlags flags = 0;
|
||
|
foreach (string mod in modifiers)
|
||
|
switch (mod) {
|
||
|
case "private":
|
||
|
flags |= nested ? TypeFlags.NestedPrivate : TypeFlags.NotPublic; break;
|
||
|
case "public":
|
||
|
flags |= nested ? TypeFlags.NestedPublic : TypeFlags.Public; break;
|
||
|
case "protected":
|
||
|
if (nested)
|
||
|
flags |= modifiers.Contains("internal") ? TypeFlags.NestedFamORAssem : TypeFlags.NestedFamily;
|
||
|
break;
|
||
|
case "internal":
|
||
|
if (nested)
|
||
|
flags |= modifiers.Contains("protected") ? TypeFlags.NestedFamORAssem : TypeFlags.NestedAssembly;
|
||
|
break;
|
||
|
case "sealed": flags |= TypeFlags.Sealed; break;
|
||
|
case "abstract": flags |= TypeFlags.Abstract; break;
|
||
|
}
|
||
|
return flags;
|
||
|
}
|
||
|
Statement goto_case_statement(goto_case_statement ast) {
|
||
|
return new GotoCase(expression(ast.expr));
|
||
|
}
|
||
|
Statement goto_default_statement(goto_default_statement ast) {
|
||
|
return new GotoCase(null);
|
||
|
}
|
||
|
Statement goto_statement(goto_statement ast) {
|
||
|
return new Goto(identifier(ast.id));
|
||
|
}
|
||
|
Identifier identifier(InputElement id) {
|
||
|
return new Identifier(id.str,
|
||
|
new SourceContext(document, id.coord.line, id.coord.column,
|
||
|
id.coord.line, id.coord.column + id.str.Length));
|
||
|
}
|
||
|
Statement if_statement(if_statement ast) {
|
||
|
Expression expr = expression(ast.expr);
|
||
|
System.Compiler.Block thenpart = block(ast.thenpart);
|
||
|
if (ast.elsepart != null)
|
||
|
return new If(expr, thenpart, block(ast.elsepart));
|
||
|
else
|
||
|
return new If(expr, thenpart, null);
|
||
|
}
|
||
|
Expression implicit_cast_expression(implicit_cast_expression ast) {
|
||
|
if (ast.ty != null)
|
||
|
type(ast.ty);
|
||
|
expression(ast.expr);
|
||
|
// [Typecheck,MayBeNull] Method ast.method
|
||
|
// Boolean ast.valueUsed
|
||
|
// [Typecheck] Type ast.typ
|
||
|
// [MayBeNull,Typecheck] Object ast.value
|
||
|
return null;
|
||
|
}
|
||
|
Node implicit_declarator(implicit_declarator ast) {
|
||
|
// InputElement ast.id1
|
||
|
type(ast.t1);
|
||
|
// [Bind1] Formal ast.sym
|
||
|
type(ast.ty);
|
||
|
// [Bind1] Method ast.method
|
||
|
return null;
|
||
|
}
|
||
|
Node indexer(indexer ast) {
|
||
|
formals(ast.f);
|
||
|
if (ast.interfacename != null)
|
||
|
name_type(ast.interfacename);
|
||
|
type(ast.ty);
|
||
|
return null;
|
||
|
}
|
||
|
Node indexer_declaration(indexer_declaration ast) {
|
||
|
foreach (accessor_declaration x in ast.accessors)
|
||
|
accessor_declaration(x);
|
||
|
foreach (attribute_section x in ast.attrs)
|
||
|
attribute_section(x);
|
||
|
indexer(ast.i);
|
||
|
// [Emit] PropertyBuilder ast.builder
|
||
|
// InputElementList ast.mods
|
||
|
return null;
|
||
|
}
|
||
|
TypeNode int_type(int_type ast) {
|
||
|
return SystemTypes.Int32;
|
||
|
}
|
||
|
Expression integer_literal(integer_literal ast) {
|
||
|
ulong n;
|
||
|
string str = ast.token.str;
|
||
|
if (str.StartsWith("0x"))
|
||
|
n = UInt64.Parse(str.Substring(2), System.Globalization.NumberStyles.HexNumber, null);
|
||
|
else
|
||
|
n = UInt64.Parse(str);
|
||
|
string suffix = null;
|
||
|
if (str.EndsWith("ul") || str.EndsWith("lu"))
|
||
|
suffix = "ul";
|
||
|
else if (str.EndsWith("u") || str.EndsWith("l"))
|
||
|
suffix = str.Substring(str.Length - 1);
|
||
|
if (n <= int.MaxValue && suffix == null)
|
||
|
return new Literal((uint)n, SystemTypes.Int32);
|
||
|
else if (n <= uint.MaxValue && (suffix == null || suffix == "u"))
|
||
|
return new Literal((uint)n, SystemTypes.UInt32);
|
||
|
else if (n <= long.MaxValue && (suffix == null || suffix == "l"))
|
||
|
return new Literal((long)n, SystemTypes.Int64);
|
||
|
else
|
||
|
return new Literal(n, SystemTypes.UInt64);
|
||
|
}
|
||
|
Node interface_declaration(interface_declaration ast) {
|
||
|
foreach (attribute_section x in ast.attrs)
|
||
|
attribute_section(x);
|
||
|
foreach (type_parameter x in ast.typeparams)
|
||
|
type_parameter(x);
|
||
|
foreach (type_parameter_constraints_clause x in ast.constraints)
|
||
|
type_parameter_constraints_clause(x);
|
||
|
foreach (declaration x in ast.body)
|
||
|
declaration(x);
|
||
|
// InputElement ast.id
|
||
|
foreach (type x in ast.interfaces)
|
||
|
type(x);
|
||
|
// [Bind1] InterfaceType ast.sym
|
||
|
// [Emit] Type ast.type
|
||
|
// InputElementList ast.mods
|
||
|
return null;
|
||
|
}
|
||
|
Node interface_event_declaration(interface_event_declaration ast) {
|
||
|
foreach (attribute_section x in ast.attrs)
|
||
|
attribute_section(x);
|
||
|
// InputElement ast.id
|
||
|
type(ast.ty);
|
||
|
// [Bind1] Event ast.sym
|
||
|
// [Emit] EventBuilder ast.builder
|
||
|
// InputElementList ast.mods
|
||
|
return null;
|
||
|
}
|
||
|
Node interface_indexer_declaration(interface_indexer_declaration ast) {
|
||
|
foreach (accessor_declaration x in ast.accessors)
|
||
|
accessor_declaration(x);
|
||
|
foreach (attribute_section x in ast.attrs)
|
||
|
attribute_section(x);
|
||
|
formals(ast.f);
|
||
|
type(ast.ty);
|
||
|
// [Emit] PropertyBuilder ast.builder
|
||
|
// InputElementList ast.mods
|
||
|
return null;
|
||
|
}
|
||
|
Node interface_method_declaration(interface_method_declaration ast) {
|
||
|
foreach (attribute_section x in ast.attrs)
|
||
|
attribute_section(x);
|
||
|
formals(ast.f);
|
||
|
// InputElement ast.id
|
||
|
type(ast.ty);
|
||
|
// [Bind1] Method ast.sym
|
||
|
// [Emit] MethodBuilder ast.builder
|
||
|
// InputElementList ast.mods
|
||
|
return null;
|
||
|
}
|
||
|
Node interface_property_declaration(interface_property_declaration ast) {
|
||
|
foreach (accessor_declaration x in ast.accessors)
|
||
|
accessor_declaration(x);
|
||
|
foreach (attribute_section x in ast.attrs)
|
||
|
attribute_section(x);
|
||
|
// InputElement ast.id
|
||
|
type(ast.ty);
|
||
|
// [Bind1] Property ast.sym
|
||
|
// [Emit] PropertyBuilder ast.builder
|
||
|
// InputElementList ast.mods
|
||
|
return null;
|
||
|
}
|
||
|
Expression invocation_expression(invocation_expression ast) {
|
||
|
ExpressionList args = new ExpressionList();
|
||
|
foreach (argument x in ast.args)
|
||
|
args.Add(argument(x));
|
||
|
return new MethodCall(expression(ast.expr), args);
|
||
|
}
|
||
|
Expression is_expression(is_expression ast) {
|
||
|
return new BinaryExpression(expression(ast.expr),
|
||
|
new MemberBinding(null, type(ast.ty)), NodeType.Is);
|
||
|
}
|
||
|
Statement labeled_statement(labeled_statement ast) {
|
||
|
LabeledStatement result = new LabeledStatement();
|
||
|
result.Label = identifier(ast.label);
|
||
|
result.Statement = statement(ast.stmt);
|
||
|
return result;
|
||
|
}
|
||
|
Expression literal(literal ast) {
|
||
|
if (ast is boolean_literal) return boolean_literal((boolean_literal)ast);
|
||
|
else if (ast is character_literal) return character_literal((character_literal)ast);
|
||
|
else if (ast is integer_literal) return integer_literal((integer_literal)ast);
|
||
|
else if (ast is null_literal) return null_literal((null_literal)ast);
|
||
|
else if (ast is real_literal) return real_literal((real_literal)ast);
|
||
|
else if (ast is string_literal) return string_literal((string_literal)ast);
|
||
|
else throw new ArgumentException();
|
||
|
}
|
||
|
Statement local_statement(local_statement ast) {
|
||
|
LocalDeclarationsStatement result = new LocalDeclarationsStatement();
|
||
|
result.Constant = false;
|
||
|
result.Type = type(ast.ty);
|
||
|
result.Declarations = new LocalDeclarationList();
|
||
|
foreach (var_declarator x in ast.vars)
|
||
|
result.Declarations.Add(var_declarator(x));
|
||
|
return result;
|
||
|
}
|
||
|
Statement lock_statement(lock_statement ast) {
|
||
|
Lock result = new Lock();
|
||
|
result.Guard = expression(ast.expr);
|
||
|
result.Body = block(ast.body);
|
||
|
return result;
|
||
|
}
|
||
|
TypeNode long_type(long_type ast) {
|
||
|
return SystemTypes.Int64;
|
||
|
}
|
||
|
Expression member_access(member_access ast) {
|
||
|
if (ast is expr_access) return expr_access((expr_access)ast);
|
||
|
else if (ast is pointer_access) return pointer_access((pointer_access)ast);
|
||
|
else if (ast is predefined_access) return predefined_access((predefined_access)ast);
|
||
|
else throw new ArgumentException();
|
||
|
}
|
||
|
Node member_name(member_name ast) {
|
||
|
// InputElement ast.id
|
||
|
if (ast.ty != null)
|
||
|
type(ast.ty);
|
||
|
// [Bind2] InterfaceType ast.sym
|
||
|
return null;
|
||
|
}
|
||
|
Node method_declaration(method_declaration ast) {
|
||
|
System.Compiler.Method result = new System.Compiler.Method();
|
||
|
foreach (attribute_section x in ast.attrs)
|
||
|
attribute_section(x);
|
||
|
result.Flags = getMethodFlags(stringList(ast.mods));
|
||
|
if (ast.body != null)
|
||
|
result.Body = block(ast.body);
|
||
|
member_name(ast.name);
|
||
|
result.Name = identifier(ast.name.id);
|
||
|
result.Parameters = formals(ast.parms);
|
||
|
for (int i = 0; i < result.Parameters.Length; i++)
|
||
|
result.Parameters[i].DeclaringMethod = result;
|
||
|
result.ReturnType = type(ast.ty);
|
||
|
return result;
|
||
|
}
|
||
|
TypeNode name_type(name_type ast) {
|
||
|
dotted_name(ast.name);
|
||
|
// [Bind2] Type ast.sym
|
||
|
return null;
|
||
|
}
|
||
|
Node named_argument(named_argument ast) {
|
||
|
expression(ast.expr);
|
||
|
// InputElement ast.id
|
||
|
return null;
|
||
|
}
|
||
|
Node namespace_body(namespace_body ast) {
|
||
|
foreach (declaration x in ast.declarations)
|
||
|
declaration(x);
|
||
|
foreach (using_directive x in ast.ud)
|
||
|
using_directive(x);
|
||
|
return null;
|
||
|
}
|
||
|
Node namespace_declaration(namespace_declaration ast) {
|
||
|
dotted_name(ast.id);
|
||
|
namespace_body(ast.nb);
|
||
|
// [Bind1] NameSpace ast.sym
|
||
|
// InputElementList ast.mods
|
||
|
return null;
|
||
|
}
|
||
|
Node namespace_directive(namespace_directive ast) {
|
||
|
dotted_name(ast.name);
|
||
|
// [Bind1] NameSpace ast.sym
|
||
|
return null;
|
||
|
}
|
||
|
Expression new_expression(new_expression ast) {
|
||
|
ExpressionList args = new ExpressionList();
|
||
|
foreach (argument x in ast.args)
|
||
|
args.Add(argument(x));
|
||
|
return new Construct(new Literal(type(ast.ty), SystemTypes.Type), args);
|
||
|
}
|
||
|
Expression null_literal(null_literal ast) {
|
||
|
return new Literal(null, SystemTypes.Object);
|
||
|
}
|
||
|
TypeNode object_type(object_type ast) {
|
||
|
return SystemTypes.Object;
|
||
|
}
|
||
|
Node operator_declaration(operator_declaration ast) {
|
||
|
foreach (attribute_section x in ast.attrs)
|
||
|
attribute_section(x);
|
||
|
if (ast.block != null)
|
||
|
statement(ast.block);
|
||
|
operator_declarator(ast.op);
|
||
|
// [Bind1] Method ast.sym
|
||
|
// InputElementList ast.mods
|
||
|
return null;
|
||
|
}
|
||
|
Node operator_declarator(operator_declarator ast) {
|
||
|
if (ast is binary_declarator) return binary_declarator((binary_declarator)ast);
|
||
|
else if (ast is explicit_declarator) return explicit_declarator((explicit_declarator)ast);
|
||
|
else if (ast is implicit_declarator) return implicit_declarator((implicit_declarator)ast);
|
||
|
else if (ast is unary_declarator) return unary_declarator((unary_declarator)ast);
|
||
|
else throw new ArgumentException();
|
||
|
}
|
||
|
Parameter parameter(parameter ast) {
|
||
|
if (ast is arglist_parameter) return arglist_parameter((arglist_parameter)ast);
|
||
|
else if (ast is fixed_parameter) return fixed_parameter((fixed_parameter)ast);
|
||
|
else if (ast is params_parameter) return params_parameter((params_parameter)ast);
|
||
|
else throw new ArgumentException();
|
||
|
}
|
||
|
Parameter params_parameter(params_parameter ast) {
|
||
|
Parameter result = new Parameter(identifier(ast.id), type(ast.ty));
|
||
|
foreach (attribute_section x in ast.attrs)
|
||
|
attribute_section(x);
|
||
|
return result;
|
||
|
}
|
||
|
Expression pointer_access(pointer_access ast) {
|
||
|
AddressDereference addr = new AddressDereference();
|
||
|
addr.Address = expression(ast.expr);
|
||
|
Expression result = new QualifiedIdentifier(addr, identifier(ast.id));
|
||
|
if (ast.typeargs != null) {
|
||
|
foreach (type x in ast.typeargs)
|
||
|
type(x);
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
TypeNode pointer_type(pointer_type ast) {
|
||
|
return new PointerTypeExpression(type(ast.ty));
|
||
|
}
|
||
|
Expression post_expression(post_expression ast) {
|
||
|
NodeType op;
|
||
|
switch (ast.op.str) {
|
||
|
case "++": op = NodeType.Increment; break;
|
||
|
case "--": op = NodeType.Decrement; break;
|
||
|
default: op = NodeType.Nop; break;
|
||
|
}
|
||
|
return new UnaryExpression(expression(ast.expr), op);
|
||
|
}
|
||
|
Expression pre_expression(pre_expression ast) {
|
||
|
NodeType op;
|
||
|
switch (ast.op.str) {
|
||
|
case "++": op = NodeType.Increment; break;
|
||
|
case "--": op = NodeType.Decrement; break;
|
||
|
default: op = NodeType.Nop; break;
|
||
|
}
|
||
|
return new UnaryExpression(expression(ast.expr), op);
|
||
|
}
|
||
|
Expression predefined_access(predefined_access ast) {
|
||
|
Expression result = new QualifiedIdentifier(
|
||
|
new Literal(type(ast.predefined.str), SystemTypes.Type),
|
||
|
identifier(ast.id));
|
||
|
if (ast.typeargs != null) {
|
||
|
foreach (type x in ast.typeargs)
|
||
|
type(x);
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
Node property_declaration(property_declaration ast) {
|
||
|
foreach (attribute_section x in ast.attrs)
|
||
|
attribute_section(x);
|
||
|
foreach (accessor_declaration x in ast.decls)
|
||
|
accessor_declaration(x);
|
||
|
member_name(ast.name);
|
||
|
type(ast.ty);
|
||
|
// [Bind1] Property ast.sym
|
||
|
// [Emit] PropertyBuilder ast.builder
|
||
|
// InputElementList ast.mods
|
||
|
return null;
|
||
|
}
|
||
|
Node qualified_alias_member(qualified_alias_member ast) {
|
||
|
// InputElement ast.qualifier
|
||
|
if (ast.left != null)
|
||
|
dotted_name(ast.left);
|
||
|
// InputElement ast.right
|
||
|
if (ast.typeargs != null)
|
||
|
foreach (type x in ast.typeargs)
|
||
|
type(x);
|
||
|
// [Bind2] Symbol ast.sym
|
||
|
return null;
|
||
|
}
|
||
|
Node qualified_name(qualified_name ast) {
|
||
|
// InputElement ast.qualifier
|
||
|
// InputElement ast.id
|
||
|
if (ast.typeargs != null)
|
||
|
foreach (type x in ast.typeargs)
|
||
|
type(x);
|
||
|
// [Bind2] Symbol ast.sym
|
||
|
// [Typecheck,MayBeNull] Method ast.method
|
||
|
// Boolean ast.valueUsed
|
||
|
// [Typecheck] Type ast.typ
|
||
|
// [MayBeNull,Typecheck] Object ast.value
|
||
|
return null;
|
||
|
}
|
||
|
Expression real_literal(real_literal ast) {
|
||
|
string str = ast.token.str;
|
||
|
try {
|
||
|
if (str.EndsWith("m"))
|
||
|
return new Literal(Decimal.Parse(str), SystemTypes.Decimal);
|
||
|
else if (str.EndsWith("f"))
|
||
|
return new Literal(Single.Parse(str), SystemTypes.Single);
|
||
|
else
|
||
|
return new Literal(Double.Parse(str), SystemTypes.Double);
|
||
|
} catch (OverflowException) {
|
||
|
return new Literal(0.0, SystemTypes.Double);
|
||
|
}
|
||
|
}
|
||
|
Statement resource(resource ast) {
|
||
|
if (ast is resource_decl) return resource_decl((resource_decl)ast);
|
||
|
else if (ast is resource_expr) return resource_expr((resource_expr)ast);
|
||
|
else throw new ArgumentException();
|
||
|
}
|
||
|
Statement resource_decl(resource_decl ast) {
|
||
|
Statement result = local_statement(ast.local);
|
||
|
result.SourceContext = context(ast);
|
||
|
return result;
|
||
|
}
|
||
|
Statement resource_expr(resource_expr ast) {
|
||
|
Statement result = expressionstatement(ast.expr);
|
||
|
result.SourceContext = context(ast);
|
||
|
return result;
|
||
|
}
|
||
|
Statement return_statement(return_statement ast) {
|
||
|
if (ast.expr != null)
|
||
|
return new Return(expression(ast.expr));
|
||
|
else
|
||
|
return new Return();
|
||
|
}
|
||
|
TypeNode sbyte_type(sbyte_type ast) {
|
||
|
return SystemTypes.Int8;
|
||
|
}
|
||
|
TypeNode short_type(short_type ast) {
|
||
|
return SystemTypes.Int16;
|
||
|
}
|
||
|
Expression simple_name(simple_name ast) {
|
||
|
Expression result = identifier(ast.id);
|
||
|
if (ast.typeargs != null) {
|
||
|
foreach (type x in ast.typeargs)
|
||
|
type(x);
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
Expression sizeof_expression(sizeof_expression ast) {
|
||
|
return new UnaryExpression(
|
||
|
new MemberBinding(null, typeexpression(ast.ty)), NodeType.Sizeof);
|
||
|
}
|
||
|
Expression stackalloc_initializer(stackalloc_initializer ast) {
|
||
|
type(ast.ty);
|
||
|
return expression(ast.expr);
|
||
|
}
|
||
|
Statement statement(statement ast) {
|
||
|
Statement result = null;
|
||
|
if (ast is block_statement) result = block_statement((block_statement)ast);
|
||
|
else if (ast is break_statement) result = break_statement((break_statement)ast);
|
||
|
else if (ast is checked_statement) result = checked_statement((checked_statement)ast);
|
||
|
else if (ast is const_statement) result = const_statement((const_statement)ast);
|
||
|
else if (ast is continue_statement) result = continue_statement((continue_statement)ast);
|
||
|
else if (ast is do_statement) result = do_statement((do_statement)ast);
|
||
|
else if (ast is empty_statement) result = empty_statement((empty_statement)ast);
|
||
|
else if (ast is expression_statement) result = expression_statement((expression_statement)ast);
|
||
|
else if (ast is fixed_statement) result = fixed_statement((fixed_statement)ast);
|
||
|
else if (ast is for_statement) result = for_statement((for_statement)ast);
|
||
|
else if (ast is foreach_statement) result = foreach_statement((foreach_statement)ast);
|
||
|
else if (ast is goto_case_statement) result = goto_case_statement((goto_case_statement)ast);
|
||
|
else if (ast is goto_default_statement) result = goto_default_statement((goto_default_statement)ast);
|
||
|
else if (ast is goto_statement) result = goto_statement((goto_statement)ast);
|
||
|
else if (ast is if_statement) result = if_statement((if_statement)ast);
|
||
|
else if (ast is labeled_statement) result = labeled_statement((labeled_statement)ast);
|
||
|
else if (ast is local_statement) result = local_statement((local_statement)ast);
|
||
|
else if (ast is lock_statement) result = lock_statement((lock_statement)ast);
|
||
|
else if (ast is return_statement) result = return_statement((return_statement)ast);
|
||
|
else if (ast is switch_statement) result = switch_statement((switch_statement)ast);
|
||
|
else if (ast is throw_statement) result = throw_statement((throw_statement)ast);
|
||
|
else if (ast is try_statement) result = try_statement((try_statement)ast);
|
||
|
else if (ast is unchecked_statement) result = unchecked_statement((unchecked_statement)ast);
|
||
|
else if (ast is unsafe_statement) result = unsafe_statement((unsafe_statement)ast);
|
||
|
else if (ast is using_statement) result = using_statement((using_statement)ast);
|
||
|
else if (ast is while_statement) result = while_statement((while_statement)ast);
|
||
|
else if (ast is yield_statement) result = yield_statement((yield_statement)ast);
|
||
|
else throw new ArgumentException();
|
||
|
result.SourceContext = context(ast);
|
||
|
return result;
|
||
|
}
|
||
|
Expression string_literal(string_literal ast) {
|
||
|
bool errorFlag;
|
||
|
return new Literal(typecheck.stringLiteral(ast.token.str, out errorFlag), SystemTypes.String);
|
||
|
}
|
||
|
TypeNode string_type(string_type ast) {
|
||
|
return SystemTypes.String;
|
||
|
}
|
||
|
stringList stringList(InputElementList srclist) {
|
||
|
stringList list = new stringList();
|
||
|
foreach (InputElement e in srclist)
|
||
|
list.Add(e.str);
|
||
|
return list;
|
||
|
}
|
||
|
Node struct_declaration(struct_declaration ast) {
|
||
|
foreach (attribute_section x in ast.attrs)
|
||
|
attribute_section(x);
|
||
|
foreach (type_parameter x in ast.typeparams)
|
||
|
type_parameter(x);
|
||
|
foreach (type_parameter_constraints_clause x in ast.constraints)
|
||
|
type_parameter_constraints_clause(x);
|
||
|
foreach (declaration x in ast.body)
|
||
|
declaration(x);
|
||
|
// InputElement ast.id
|
||
|
foreach (type x in ast.interfaces)
|
||
|
type(x);
|
||
|
// [Bind1] StructType ast.sym
|
||
|
// [Emit] Type ast.type
|
||
|
// InputElementList ast.mods
|
||
|
return null;
|
||
|
}
|
||
|
SwitchCase switch_default(switch_default ast) {
|
||
|
return new SwitchCase(null, null);
|
||
|
}
|
||
|
SwitchCase switch_expression(switch_expression ast) {
|
||
|
return new SwitchCase(expression(ast.expr), null);
|
||
|
}
|
||
|
SwitchCase switch_label(switch_label ast) {
|
||
|
if (ast is switch_default) return switch_default((switch_default)ast);
|
||
|
else if (ast is switch_expression) return switch_expression((switch_expression)ast);
|
||
|
else throw new ArgumentException();
|
||
|
}
|
||
|
void switch_section(switch_section ast, SwitchCaseList cases) {
|
||
|
foreach (switch_label x in ast.labels)
|
||
|
cases.Add(switch_label(x));
|
||
|
StatementList stmts = new StatementList();
|
||
|
cases[cases.Length-1].Body = new System.Compiler.Block(stmts);
|
||
|
foreach (statement x in ast.stmts)
|
||
|
stmts.Add(statement(x));
|
||
|
}
|
||
|
Statement switch_statement(switch_statement ast) {
|
||
|
Switch result = new Switch(expression(ast.expr), new SwitchCaseList());
|
||
|
foreach (switch_section x in ast.sections)
|
||
|
switch_section(x, result.Cases);
|
||
|
return result;
|
||
|
}
|
||
|
Expression this_access(this_access ast) {
|
||
|
return new This();
|
||
|
}
|
||
|
Node this_initializer(this_initializer ast) {
|
||
|
foreach (argument x in ast.args)
|
||
|
argument(x);
|
||
|
// [Typecheck] Constructor ast.method
|
||
|
return null;
|
||
|
}
|
||
|
Statement throw_statement(throw_statement ast) {
|
||
|
if (ast.expr != null)
|
||
|
return new Throw(expression(ast.expr));
|
||
|
else
|
||
|
return new Throw();
|
||
|
}
|
||
|
Statement try_statement(try_statement ast) {
|
||
|
Try result = new Try();
|
||
|
result.TryBlock = block(ast.block);
|
||
|
if (ast.catches != null)
|
||
|
result.Catchers = catch_clauses(ast.catches);
|
||
|
if (ast.finally_block != null)
|
||
|
result.Finally = finally_clause(ast.finally_block);
|
||
|
return result;
|
||
|
}
|
||
|
TypeNode type(type ast) {
|
||
|
TypeNode result = null;
|
||
|
if (ast is array_type) result = array_type((array_type)ast);
|
||
|
else if (ast is bool_type) result = bool_type((bool_type)ast);
|
||
|
else if (ast is byte_type) result = byte_type((byte_type)ast);
|
||
|
else if (ast is char_type) result = char_type((char_type)ast);
|
||
|
else if (ast is constructor_constraint) result = constructor_constraint((constructor_constraint)ast);
|
||
|
else if (ast is decimal_type) result = decimal_type((decimal_type)ast);
|
||
|
else if (ast is double_type) result = double_type((double_type)ast);
|
||
|
else if (ast is float_type) result = float_type((float_type)ast);
|
||
|
else if (ast is int_type) result = int_type((int_type)ast);
|
||
|
else if (ast is long_type) result = long_type((long_type)ast);
|
||
|
else if (ast is name_type) result = name_type((name_type)ast);
|
||
|
else if (ast is object_type) result = object_type((object_type)ast);
|
||
|
else if (ast is pointer_type) result = pointer_type((pointer_type)ast);
|
||
|
else if (ast is sbyte_type) result = sbyte_type((sbyte_type)ast);
|
||
|
else if (ast is short_type) result = short_type((short_type)ast);
|
||
|
else if (ast is string_type) result = string_type((string_type)ast);
|
||
|
else if (ast is type_parameter) result = type_parameter((type_parameter)ast);
|
||
|
else if (ast is uint_type) result = uint_type((uint_type)ast);
|
||
|
else if (ast is ulong_type) result = ulong_type((ulong_type)ast);
|
||
|
else if (ast is ushort_type) result = ushort_type((ushort_type)ast);
|
||
|
else if (ast is void_pointer_type) result = void_pointer_type((void_pointer_type)ast);
|
||
|
else if (ast is void_type) result = void_type((void_type)ast);
|
||
|
else throw new ArgumentException();
|
||
|
result.SourceContext = context(ast);
|
||
|
return result;
|
||
|
}
|
||
|
TypeNode type(string id) {
|
||
|
switch (id) {
|
||
|
case "bool": return SystemTypes.Boolean;
|
||
|
case "decimal": return SystemTypes.Decimal;
|
||
|
case "sbyte": return SystemTypes.Int8;
|
||
|
case "byte": return SystemTypes.UInt8;
|
||
|
case "short": return SystemTypes.Int16;
|
||
|
case "ushort": return SystemTypes.UInt16;
|
||
|
case "int": return SystemTypes.Int32;
|
||
|
case "uint": return SystemTypes.UInt32;
|
||
|
case "long": return SystemTypes.Int64;
|
||
|
case "ulong": return SystemTypes.UInt64;
|
||
|
case "char": return SystemTypes.Char;
|
||
|
case "float": return SystemTypes.Single;
|
||
|
case "double": return SystemTypes.Double;
|
||
|
case "object": return SystemTypes.Object;
|
||
|
case "string": return SystemTypes.String;
|
||
|
case "void": return SystemTypes.Void;
|
||
|
default: return null;
|
||
|
}
|
||
|
}
|
||
|
Node type_declaration(type_declaration ast) {
|
||
|
if (ast is class_declaration) return class_declaration((class_declaration)ast);
|
||
|
else if (ast is delegate_declaration) return delegate_declaration((delegate_declaration)ast);
|
||
|
else if (ast is enum_declaration) return enum_declaration((enum_declaration)ast);
|
||
|
else if (ast is interface_declaration) return interface_declaration((interface_declaration)ast);
|
||
|
else if (ast is struct_declaration) return struct_declaration((struct_declaration)ast);
|
||
|
else throw new ArgumentException();
|
||
|
}
|
||
|
TypeExpression typeexpression(type ast) {
|
||
|
TypeNode t = type(ast);
|
||
|
TypeExpression result = new TypeExpression(new Literal(t, SystemTypes.Type), t.SourceContext);
|
||
|
result.Name = t.Name;
|
||
|
return result;
|
||
|
}
|
||
|
TypeNode type_parameter(type_parameter ast) {
|
||
|
foreach (attribute_section x in ast.attrs)
|
||
|
attribute_section(x);
|
||
|
// InputElement ast.id
|
||
|
// [Bind2] Type ast.sym
|
||
|
return null;
|
||
|
}
|
||
|
Node type_parameter_constraints_clause(type_parameter_constraints_clause ast) {
|
||
|
// InputElement ast.id
|
||
|
foreach (type x in ast.constraints)
|
||
|
type(x);
|
||
|
return null;
|
||
|
}
|
||
|
Expression typeof_expression(typeof_expression ast) {
|
||
|
return new UnaryExpression(
|
||
|
new MemberBinding(null, typeexpression(ast.ty)), NodeType.Typeof);
|
||
|
}
|
||
|
TypeNode uint_type(uint_type ast) {
|
||
|
return SystemTypes.UInt32;
|
||
|
}
|
||
|
TypeNode ulong_type(ulong_type ast) {
|
||
|
return SystemTypes.UInt64;
|
||
|
}
|
||
|
Node unary_declarator(unary_declarator ast) {
|
||
|
// InputElement ast.id1
|
||
|
// InputElement ast.op
|
||
|
type(ast.t1);
|
||
|
// [Bind1] Formal ast.sym
|
||
|
type(ast.ty);
|
||
|
// [Bind1] Method ast.method
|
||
|
return null;
|
||
|
}
|
||
|
Expression unary_expression(unary_expression ast) {
|
||
|
NodeType op;
|
||
|
switch (ast.op.str) {
|
||
|
case "+": op = NodeType.UnaryPlus; break;
|
||
|
case "~": op = NodeType.Not; break;
|
||
|
case "-": op = NodeType.Neg; break;
|
||
|
case "!": op = NodeType.LogicalNot; break;
|
||
|
case "&": op = NodeType.AddressOf; break;
|
||
|
default: op = NodeType.Nop; break;
|
||
|
}
|
||
|
return new UnaryExpression(expression(ast.expr), op);
|
||
|
}
|
||
|
Expression unchecked_expression(unchecked_expression ast) {
|
||
|
BlockExpression result = new BlockExpression();
|
||
|
result.Block = new System.Compiler.Block(new StatementList(expressionstatement(ast.expr)), false, true);
|
||
|
return result;
|
||
|
}
|
||
|
Statement unchecked_statement(unchecked_statement ast) {
|
||
|
System.Compiler.Block result = block(ast.stmt);
|
||
|
result.Checked = false;
|
||
|
result.SuppressCheck = true;
|
||
|
return result;
|
||
|
}
|
||
|
Statement unsafe_statement(unsafe_statement ast) {
|
||
|
return block(ast.block);
|
||
|
}
|
||
|
TypeNode ushort_type(ushort_type ast) {
|
||
|
return SystemTypes.UInt16;
|
||
|
}
|
||
|
Node using_directive(using_directive ast) {
|
||
|
if (ast is alias_directive) return alias_directive((alias_directive)ast);
|
||
|
else if (ast is namespace_directive) return namespace_directive((namespace_directive)ast);
|
||
|
else throw new ArgumentException();
|
||
|
}
|
||
|
Statement using_statement(using_statement ast) {
|
||
|
ResourceUse result = new ResourceUse();
|
||
|
result.ResourceAcquisition = resource(ast.r);
|
||
|
result.Body = block(ast.body);
|
||
|
return result;
|
||
|
}
|
||
|
LocalDeclaration var_declarator(var_declarator ast) {
|
||
|
if (ast.init != null)
|
||
|
return new LocalDeclaration(identifier(ast.id), variable_initializer(ast.init));
|
||
|
else
|
||
|
return new LocalDeclaration(identifier(ast.id), null);
|
||
|
}
|
||
|
Expression variable_initializer(variable_initializer ast) {
|
||
|
if (ast is array_initializer) return array_initializer((array_initializer)ast);
|
||
|
else if (ast is expr_initializer) return expr_initializer((expr_initializer)ast);
|
||
|
else if (ast is stackalloc_initializer) return stackalloc_initializer((stackalloc_initializer)ast);
|
||
|
else throw new ArgumentException();
|
||
|
}
|
||
|
TypeNode void_pointer_type(void_pointer_type ast) {
|
||
|
return new PointerTypeExpression(SystemTypes.Void);
|
||
|
}
|
||
|
TypeNode void_type(void_type ast) {
|
||
|
return SystemTypes.Void;
|
||
|
}
|
||
|
Statement while_statement(while_statement ast) {
|
||
|
return new While(expression(ast.expr), block(ast.body));
|
||
|
}
|
||
|
Statement yield_break_statement(yield_break_statement ast) {
|
||
|
return new Yield();
|
||
|
}
|
||
|
Statement yield_return_statement(yield_return_statement ast) {
|
||
|
return new Yield(expression(ast.expr));
|
||
|
}
|
||
|
Statement yield_statement(yield_statement ast) {
|
||
|
if (ast is yield_return_statement) return yield_return_statement((yield_return_statement)ast);
|
||
|
else if (ast is yield_break_statement) return yield_break_statement((yield_break_statement)ast);
|
||
|
else throw new ArgumentException();
|
||
|
}
|
||
|
}
|