Ejemplo n.º 1
0
        public static void New()
        {
            CompilationScope mainScope = new CompilationScope
            {
                instructions        = new Instructions {
                },
                lastInstruction     = new EmittedInstruction {
                },
                previousInstruction = new EmittedInstruction {
                },
            };

            symbol_table.SymbolTable symbolTable = symbol_table.NewSymbolTable();

            for (int i = 0; i < Object.builtins.Builtins.Length; i++)
            {
                Object._BuiltinDefinition v = Object.builtins.Builtins[i];
                symbol_table.DefineBuiltin(ref symbolTable, i, v.Name);
            }

            compiler = new Compiler_t
            {
                constants   = new List <Object.Object>(),
                symbolTable = symbolTable,
                scopes      = new List <CompilationScope> {
                    mainScope
                },
                scopeIndex = 0,
            };
        }
Ejemplo n.º 2
0
        public static error Run()
        {
            int          ip;
            Instructions ins;
            Opcode       op;

            while (currentFrame().ip < Frame.Instructions(currentFrame()).Count - 1)
            {
                vm.frames[vm.frameIndex - 1].ip++;

                ip  = currentFrame().ip;
                ins = Frame.Instructions(currentFrame());
                op  = (Opcode)ins[ip];

                switch (op)
                {
                case code.OpConstant:
                {
                    int constIndex = code.ReadUint16(ins, ip + 1);
                    vm.frames[vm.frameIndex - 1].ip += 2;

                    error err = push(vm.constants[constIndex]);
                    if (err != null)
                    {
                        return(err);
                    }
                }
                break;

                case code.OpPop:
                    pop();
                    break;

                case code.OpAdd:
                case code.OpSub:
                case code.OpMul:
                case code.OpDiv:
                {
                    error err = executeBinaryOperation(op);
                    if (err != null)
                    {
                        return(err);
                    }
                }
                break;

                case code.OpTrue:
                {
                    error err = push(True);
                    if (err != null)
                    {
                        return(err);
                    }
                }
                break;

                case code.OpFalse:
                {
                    error err = push(False);
                    if (err != null)
                    {
                        return(err);
                    }
                }
                break;

                case code.OpEqual:
                case code.OpNotEqual:
                case code.OpGreaterThan:
                {
                    error err = executeComparison(op);
                    if (err != null)
                    {
                        return(err);
                    }
                }
                break;

                case code.OpBang:
                {
                    error err = executeBangOperator();
                    if (err != null)
                    {
                        return(err);
                    }
                }
                break;

                case code.OpMinus:
                {
                    error err = executeMinusOperator();
                    if (err != null)
                    {
                        return(err);
                    }
                }
                break;

                case code.OpJump:
                {
                    int pos = (int)code.ReadUint16(ins, ip + 1);
                    vm.frames[vm.frameIndex - 1].ip = pos - 1;
                }
                break;

                case code.OpJumpNotTruthy:
                {
                    int pos = (int)code.ReadUint16(ins, ip + 1);
                    vm.frames[vm.frameIndex - 1].ip += 2;

                    Object.Object condition = pop();
                    if (!isTruthy(condition))
                    {
                        vm.frames[vm.frameIndex - 1].ip = pos - 1;
                    }
                }
                break;

                case code.OpNull:
                {
                    error err = push(Null);
                    if (err != null)
                    {
                        return(err);
                    }
                }
                break;

                case code.OpSetGlobal:
                {
                    int globalIndex = code.ReadUint16(ins, ip + 1);

                    vm.frames[vm.frameIndex - 1].ip += 2;

                    vm.globals[globalIndex] = pop();
                }
                break;

                case code.OpGetGlobal:
                {
                    int globalIndex = code.ReadUint16(ins, ip + 1);

                    vm.frames[vm.frameIndex - 1].ip += 2;

                    error err = push(vm.globals[globalIndex]);
                    if (err != null)
                    {
                        return(err);
                    }
                }
                break;

                case code.OpArray:
                {
                    int numElements = (int)code.ReadUint16(ins, ip + 1);
                    vm.frames[vm.frameIndex - 1].ip += 2;

                    Object.Object array = buildArray(vm.sp - numElements, vm.sp);
                    vm.sp = vm.sp - numElements;

                    error err = push(array);
                    if (err != null)
                    {
                        return(err);
                    }
                }
                break;

                case code.OpHash:
                {
                    int numElements = (int)code.ReadUint16(ins, ip + 1);
                    vm.frames[vm.frameIndex - 1].ip += 2;

                    error         err;
                    Object.Object hash = buildHash(vm.sp - numElements, vm.sp, out err);
                    if (err != null)
                    {
                        return(err);
                    }
                    vm.sp = vm.sp - numElements;

                    err = push(hash);
                    if (err != null)
                    {
                        return(err);
                    }
                }
                break;

                case code.OpIndex:
                {
                    Object.Object index = pop();
                    Object.Object left  = pop();

                    error err = executeIndexExpression(left, index);
                    if (err != null)
                    {
                        return(err);
                    }
                }
                break;

                case code.OpCall:
                {
                    int numArgs = (int)code.ReadUint8(ins, ip + 1);
                    vm.frames[vm.frameIndex - 1].ip += 1;

                    error err = executeCall(numArgs);
                    if (err != null)
                    {
                        return(err);
                    }
                }
                break;

                case code.OpReturnValue:
                {
                    Object.Object returnValue = pop();

                    Frame_t frame = popFrame();
                    vm.sp = frame.basePointer - 1;

                    error err = push(returnValue);
                    if (err != null)
                    {
                        return(err);
                    }
                }
                break;

                case code.OpReturn:
                {
                    Frame_t frame = popFrame();
                    vm.sp = frame.basePointer - 1;

                    error err = push(Null);
                    if (err != null)
                    {
                        return(err);
                    }
                }
                break;

                case code.OpSetLocal:
                {
                    int localIndex = (int)code.ReadUint8(ins, ip + 1);
                    vm.frames[vm.frameIndex - 1].ip += 1;

                    Frame_t frame = currentFrame();

                    vm.stack[frame.basePointer + localIndex] = pop();
                }

                break;

                case code.OpGetLocal:
                {
                    int localIndex = (int)code.ReadUint8(ins, ip + 1);
                    vm.frames[vm.frameIndex - 1].ip += 1;

                    Frame_t frame = currentFrame();

                    error err = push(vm.stack[frame.basePointer + localIndex]);
                    if (err != null)
                    {
                        return(err);
                    }
                }
                break;

                case code.OpGetBuiltin:
                {
                    int builtinIndex = (int)code.ReadUint8(ins, ip + 1);
                    vm.frames[vm.frameIndex - 1].ip += 1;

                    Object._BuiltinDefinition definition = Object.builtins.Builtins[builtinIndex];

                    error err = push(definition.Builtin);
                    if (err != null)
                    {
                        return(err);
                    }
                }
                break;

                case code.OpClosure:
                {
                    int constIndex = (int)code.ReadUint16(ins, ip + 1);
                    int numFree    = (int)code.ReadUint8(ins, ip + 3);
                    vm.frames[vm.frameIndex - 1].ip += 3;

                    error err = pushClosure(constIndex, numFree);
                    if (err != null)
                    {
                        return(err);
                    }
                }
                break;

                case code.OpGetFree:
                {
                    int freeIndex = (int)code.ReadUint8(ins, ip + 1);
                    vm.frames[vm.frameIndex - 1].ip += 1;

                    Object.Closure curentClosure = currentFrame().cl;
                    error          err           = push(curentClosure.Free[freeIndex]);
                    if (err != null)
                    {
                        return(err);
                    }
                }
                break;

                case code.OpCurrentClosure:
                {
                    Object.Closure currentClosure = currentFrame().cl;
                    error          err            = push(currentClosure);
                    if (err != null)
                    {
                        return(err);
                    }
                }
                break;
                }
            }

            return(null);
        }