Beispiel #1
0
 internal BuiltInUnitDefinition ResolveBuiltIn(UnitReference unitReference)
 {
     try
     {
         return(RuntimeUnits.Single(unit => unit == unitReference));
     }
     catch (InvalidOperationException)
     {
         throw new UnitNotFoundException(this, unitReference);
     }
 }
Beispiel #2
0
 public UnitDefinition Resolve(UnitReference unitReference)
 {
     try
     {
         return(AllUnits.Single(unit => unit == unitReference));
     }
     catch (InvalidOperationException)
     {
         throw new UnitNotFoundException(this, unitReference);
     }
 }
Beispiel #3
0
        /// <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);
        }
Beispiel #4
0
        /// <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");
            }
        }
Beispiel #5
0
 public RoutineReference(UnitReference unitReference, Identifier name)
 {
     Name    = name;
     Unit    = unitReference;
     Context = Unit.Context;
 }
Beispiel #6
0
 public UnitNotFoundException(Context ctx, UnitReference unit)
 {
     Context = ctx;
     Unit    = unit;
 }
Beispiel #7
0
 public LiteralsNotSupported(UnitReference unit, string literal)
 {
     Unit    = unit;
     Literal = literal;
 }
Beispiel #8
0
 public LoadFromLiteralException(UnitReference unit, string literal)
 {
     Unit    = unit;
     Literal = literal;
 }