namespace arookas { class sunStorableReference : sunNode, sunTerm { public sunIdentifier Storable { get { return this[0] as sunIdentifier; } } public sunStorableReference(sunSourceLocation location) : base(location) { } public override void Compile(sunCompiler compiler) { compiler.Context.MustResolveStorable(Storable).Compile(compiler); } sunExpressionFlags sunTerm.GetExpressionFlags(sunContext context) { var symbol = context.MustResolveStorable(Storable); if (symbol is sunVariableSymbol) { return sunExpressionFlags.Variables | sunExpressionFlags.Dynamic; } else if (symbol is sunConstantSymbol) { return sunExpressionFlags.Constants; } return sunExpressionFlags.None; } } class sunVariableDeclaration : sunNode { public sunIdentifier Variable { get { return this[0] as sunIdentifier; } } public sunVariableDeclaration(sunSourceLocation location) : base(location) { } public override void Compile(sunCompiler compiler) { compiler.Context.DeclareVariable(Variable); } } class sunVariableDefinition : sunNode { public sunIdentifier Variable { get { return this[0] as sunIdentifier; } } public sunAssign Operator { get { return this[1] as sunAssign; } } public sunExpression Expression { get { return this[2] as sunExpression; } } public sunVariableDefinition(sunSourceLocation location) : base(location) { } public override void Compile(sunCompiler compiler) { var symbol = compiler.Context.DeclareVariable(Variable); Operator.Compile(compiler, symbol, Expression); } } class sunStorableAssignment : sunNode { public sunIdentifier Storable { get { return this[0] as sunIdentifier; } } public sunAssign Operator { get { return this[1] as sunAssign; } } public sunExpression Expression { get { return this[2] as sunExpression; } } public sunStorableAssignment(sunSourceLocation location) : base(location) { } public override void Compile(sunCompiler compiler) { var symbol = compiler.Context.MustResolveStorable(Storable); if (symbol is sunConstantSymbol) { throw new sunAssignConstantException(Storable); } Operator.Compile(compiler, symbol, Expression); } } class sunConstantDefinition : sunNode { public sunIdentifier Constant { get { return this[0] as sunIdentifier; } } public sunExpression Expression { get { return this[2] as sunExpression; } } public sunConstantDefinition(sunSourceLocation location) : base(location) { } public override void Compile(sunCompiler compiler) { // analyze the expression. this does two things: // 1) prevents recursion (i.e. the const referencing itself) // 2) asserts actual constness var flags = Expression.Analyze(compiler.Context); if (flags.HasFlag(sunExpressionFlags.Dynamic)) { throw new sunConstantExpressionException(Expression); } compiler.Context.DeclareConstant(Constant, Expression); } } }