public override void EmitLoad(ByteCodeBuilder code) { var operandType = Type; if (operandType is BasicType { TypeCode : BasicTypeCode.Float } ||
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))
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))
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); } } }
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(); }
public override void Emit(ByteCodeBuilder code, IEnumerable <BoundExpression> args) => EmitTextLabelAndArg(code, Opcode.TEXT_LABEL_APPEND_STRING, args);
public abstract void Emit(ByteCodeBuilder code, IEnumerable <BoundExpression> args);
public override void Emit(ByteCodeBuilder code, IEnumerable <BoundExpression> args) { args.Single().EmitLoad(code); code.Emit(Opcode.F2V); }
public override void Emit(ByteCodeBuilder code, BoundFunction parent) => throw new NotSupportedException();
public abstract void Emit(ByteCodeBuilder code, BoundFunction parent);
public override void EmitAddr(ByteCodeBuilder code) => throw new NotSupportedException();
public abstract void EmitAddr(ByteCodeBuilder code);
public abstract void EmitStore(ByteCodeBuilder code);
public abstract void EmitLoad(ByteCodeBuilder code);