internal BuiltInUnitDefinition ResolveBuiltIn(UnitReference unitReference) { try { return(RuntimeUnits.Single(unit => unit == unitReference)); } catch (InvalidOperationException) { throw new UnitNotFoundException(this, unitReference); } }
public UnitDefinition Resolve(UnitReference unitReference) { try { return(AllUnits.Single(unit => unit == unitReference)); } catch (InvalidOperationException) { throw new UnitNotFoundException(this, unitReference); } }
/// <summary> /// Generate "VARIABLE" declaration, evaluate its initializer and assign. /// </summary> /// <para>Stack behavior: expects nothing, leaves nothing.</para> /// <param name="declaration">SLang IR variable declaration.</param> private void GenerateVariableDeclaration(VariableDeclaration declaration) { var name = declaration.Name; var varType = new UnitReference(Context, declaration.Type).Resolve(); Variable variable = new BodyVariable(varType, name); // declare in the current scope scopeCurrent.Declare(name, variable); // evaluate initializer var exprType = GenerateExpression(declaration.Initializer); // assign variable.Store(ip); // verify varType.AssertIsAssignableFrom(exprType); }
/// <summary> /// Generate code which evaluates expression and stores its result into a local variable. /// </summary> /// <para>Stack behavior:</para> /// <list type="number"> /// <item><description>recursively evaluate expression</description></item> /// <item><description>leave result on the stack</description></item> /// </list> /// <param name="expression">"EXPRESSION" AST fragment</param> /// <returns>Type of evaluated expression</returns> private UnitDefinition GenerateExpression(Expression expression) { switch (expression) { case null: return(Context.TypeSystem.Void); case Literal literal: var unit = new UnitReference(Context, literal.Type).Resolve(); if (!unit.CanLoadFromLiteral) { throw new LiteralsNotSupported(unit, literal.Value); } if (unit is BuiltInUnitDefinition u) { var storage = new VariableDefinition(u.NativeType); ip.Body.Variables.Add(storage); ip.Emit(OpCodes.Ldloca, storage); u.LoadFromLiteral(literal.Value, ip); ip.Emit(OpCodes.Call, u.Ctor); ip.Emit(OpCodes.Ldloc, storage); } return(unit); case Call call: var routine = GenerateCall(call); return(routine.SignatureDefinition.ReturnType); case Reference reference: return(GenerateLoadReference(reference)); // TODO: more expression classes default: throw new NotImplementedException("Some expressions are not implemented"); } }
public RoutineReference(UnitReference unitReference, Identifier name) { Name = name; Unit = unitReference; Context = Unit.Context; }
public UnitNotFoundException(Context ctx, UnitReference unit) { Context = ctx; Unit = unit; }
public LiteralsNotSupported(UnitReference unit, string literal) { Unit = unit; Literal = literal; }
public LoadFromLiteralException(UnitReference unit, string literal) { Unit = unit; Literal = literal; }