Пример #1
0
        public override void EmitLoad(ByteCodeBuilder code)
        {
            var operandType = Type;

            if (operandType is BasicType {
                TypeCode : BasicTypeCode.Float
            } ||
Пример #2
0
 private static void LoadArguments(ByteCodeBuilder code, IEnumerable <Type> parameterTypes, IEnumerable <BoundExpression> arguments)
 {
     foreach (var(arg, paramType) in  arguments.Zip(parameterTypes))
     {
         if (paramType is RefType ||
             (paramType is BasicType {
             TypeCode: BasicTypeCode.String
         } && arg.Type?.UnderlyingType is TextLabelType))
Пример #3
0
        public override void Emit(ByteCodeBuilder code, BoundFunction parent)
        {
            EmitArrayLengthInitializers(Var.Type, parent.GetLocalLocation(Var) !.Value, code);
            var initializer = Var.Initializer;

            if (initializer != null)
            {
                if (Var.Type is RefType ||
                    (Var.Type is BasicType {
                    TypeCode : BasicTypeCode.String
                } && initializer.Type?.UnderlyingType is TextLabelType))
Пример #4
0
        public static void Emit(ByteCodeBuilder code, BoundExpression callee, IEnumerable <BoundExpression> arguments, bool dropReturnValue)
        {
            int returnValueSize = 0;

            if (callee is BoundFunctionExpression funcExpr)
            {
                returnValueSize = funcExpr.Function.Type.ReturnType?.SizeOf ?? 0;
                switch (funcExpr.Function)
                {
                case NativeFunctionSymbol n:
                    LoadArguments(code, n.Type.Parameters.Select(p => p.Type), arguments);
                    code.EmitNative(n);
                    break;

                case IntrinsicFunctionSymbol i:
                    i.Emit(code, arguments);
                    break;

                case DefinedFunctionSymbol d:
                    LoadArguments(code, d.Type.Parameters.Select(p => p.Type), arguments);
                    code.EmitCall(d);
                    break;

                default: throw new InvalidOperationException("Unknown function symbol");
                }
            }
            else // indirect call
            {
                if (callee.Type is not FunctionType funcTy)
                {
                    throw new InvalidOperationException("Only function types can be called");
                }

                Debug.Assert(funcTy is ExplicitFunctionType, $"Only {nameof(DefinedFunctionSymbol)}s can be called indirectly, so the type should be {nameof(ExplicitFunctionType)}");

                returnValueSize = funcTy.ReturnType?.SizeOf ?? 0;
                LoadArguments(code, (funcTy as ExplicitFunctionType) !.Parameters.Select(p => p.Type), arguments);
                callee.EmitLoad(code);
                code.EmitIndirectCall();
            }

            if (dropReturnValue)
            {
                for (int i = 0; i < returnValueSize; i++)
                {
                    code.Emit(ScriptAssembly.Opcode.DROP);
                }
            }
        }
Пример #5
0
        public void Emit(ByteCodeBuilder code)
        {
            code.BeginModule(this);
            var main = Functions.SingleOrDefault(f => f.Function.IsMain);

            if (main != null)
            {
                // if we have MAIN, emit before any other function
                main.Emit(code);
            }

            foreach (var func in Functions.Where(f => f != main))
            {
                func.Emit(code);
            }
            code.EndModule();
        }
Пример #6
0
 public override void Emit(ByteCodeBuilder code, IEnumerable <BoundExpression> args)
 => EmitTextLabelAndArg(code, Opcode.TEXT_LABEL_APPEND_STRING, args);
Пример #7
0
 public abstract void Emit(ByteCodeBuilder code, IEnumerable <BoundExpression> args);
Пример #8
0
 public override void Emit(ByteCodeBuilder code, IEnumerable <BoundExpression> args)
 {
     args.Single().EmitLoad(code);
     code.Emit(Opcode.F2V);
 }
Пример #9
0
 public override void Emit(ByteCodeBuilder code, BoundFunction parent) => throw new NotSupportedException();
Пример #10
0
 public abstract void Emit(ByteCodeBuilder code, BoundFunction parent);
Пример #11
0
 public override void EmitAddr(ByteCodeBuilder code) => throw new NotSupportedException();
Пример #12
0
 public abstract void EmitAddr(ByteCodeBuilder code);
Пример #13
0
 public abstract void EmitStore(ByteCodeBuilder code);
Пример #14
0
 public abstract void EmitLoad(ByteCodeBuilder code);