dvander@195: /* vim: set ts=4 sw=4 tw=99 et: dvander@195: * dvander@195: * Copyright (C) 2012 David Anderson dvander@195: * dvander@195: * This file is part of JITCraft. dvander@195: * dvander@195: * JITCraft is free software: you can redistribute it and/or modify it under dvander@195: * the terms of the GNU General Public License as published by the Free dvander@195: * Software Foundation, either version 3 of the License, or (at your option) dvander@195: * any later version. dvander@195: * dvander@195: * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY dvander@195: * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS dvander@195: * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. dvander@195: * dvander@195: * You should have received a copy of the GNU General Public License along with dvander@195: * JITCraft. If not, see http://www.gnu.org/licenses/. dvander@195: */ dvander@195: #ifndef _include_bytecode_compiler_h_ dvander@195: #define _include_bytecode_compiler_h_ dvander@195: dvander@195: #include "../Functions.h" dvander@195: #include "AST.h" dvander@195: #include "BytecodeEmitter.h" dvander@195: dvander@195: namespace ke { dvander@195: dvander@195: class Module; dvander@195: class Array; dvander@195: class ArrayMap; dvander@195: dvander@195: struct ModuleData dvander@195: { dvander@195: ScopedRoot module; dvander@195: PoolList > publics; dvander@195: ScopedRoot natives; dvander@195: }; dvander@195: dvander@195: class BytecodeCompiler : public AstVisitor dvander@195: { dvander@195: Zone *zone_; dvander@195: ParseTree *tree_; dvander@195: BytecodeEmitter emitter_; dvander@195: ScopedRoot locals_; dvander@195: Scope *scope_; dvander@195: ModuleData *moduleData_; dvander@195: dvander@195: class LoopScope dvander@195: { dvander@195: Scope *scope_; dvander@195: BytecodeEmitter::Label *bk_; dvander@195: BytecodeEmitter::Label *ct_; dvander@195: LoopScope **prevp_; dvander@195: LoopScope *prev_; dvander@195: dvander@195: public: dvander@195: LoopScope(Scope *scope, BytecodeEmitter::Label *bk, BytecodeEmitter::Label *ct, dvander@195: LoopScope **prevp) dvander@195: : scope_(scope), dvander@195: bk_(bk), dvander@195: ct_(ct), dvander@195: prevp_(prevp), dvander@195: prev_(*prevp) dvander@195: { dvander@195: *prevp_ = this; dvander@195: } dvander@195: dvander@195: ~LoopScope() dvander@195: { dvander@195: *prevp_ = prev_; dvander@195: } dvander@195: dvander@195: BytecodeEmitter::Label *break_() { dvander@195: return bk_; dvander@195: } dvander@195: BytecodeEmitter::Label *continue_() { dvander@195: return ct_; dvander@195: } dvander@195: Scope *scope() { dvander@195: return scope_; dvander@195: } dvander@195: }; dvander@195: dvander@195: LoopScope *loop_; dvander@195: dvander@195: public: dvander@195: class AutoEnterScope dvander@195: { dvander@195: BytecodeCompiler *bc_; dvander@195: Scope *saved_; dvander@195: dvander@195: public: dvander@195: AutoEnterScope(BytecodeCompiler *bc, Scope *scope) dvander@195: : bc_(bc), dvander@195: saved_(bc->scope_) dvander@195: { dvander@195: if (scope) dvander@195: bc->scope_ = scope; dvander@195: } dvander@195: ~AutoEnterScope() { dvander@195: bc_->scope_ = saved_; dvander@195: } dvander@195: }; dvander@195: dvander@195: private: dvander@195: void recordLifoSlot(Scope *scope); dvander@195: void unwindTo(Scope *scope); dvander@195: void visitForTest(Expression *expression, dvander@195: BytecodeEmitter::Label *trueBranch, dvander@195: BytecodeEmitter::Label *falseBranch, dvander@195: BytecodeEmitter::Label *fallthrough); dvander@195: Code *compileCode(Scope *scope, unsigned lineno); dvander@195: Function *compileFunction(ModuleData *module, FunctionStatement *fun); dvander@195: void visitForALU(Type *needed, Expression *node); dvander@195: dvander@195: void getEnvSlot(Variable *var); dvander@195: void setEnvSlot(Variable *var); dvander@195: dvander@195: bool tableswitch(SwitchStatement *node); dvander@195: dvander@195: public: dvander@195: BytecodeCompiler(Zone *zone, ParseTree *tree, ModuleData *module); dvander@195: dvander@195: Module *compile(); dvander@195: dvander@195: public: dvander@195: void visit(NameProxy *name); dvander@195: void visit(Assignment *node); dvander@195: void visit(BinaryExpression *node); dvander@195: void visit(ReturnStatement *node); dvander@195: void visit(ForStatement *node); dvander@195: void visit(BlockStatement *node); dvander@195: void visit(VariableDeclaration *node); dvander@195: void visit(IntegerLiteral *node); dvander@195: void visit(BooleanLiteral *node); dvander@195: void visit(FloatLiteral *node); dvander@195: void visit(StringLiteral *node); dvander@195: void visit(ExpressionStatement *node); dvander@195: void visit(FunctionStatement *node); dvander@195: void visit(CallExpression *node); dvander@195: void visit(IfStatement *node); dvander@195: void visit(IndexExpression *node); dvander@195: void visit(EnumStatement *node); dvander@195: void visit(WhileStatement *node); dvander@195: void visit(BreakStatement *node); dvander@195: void visit(ContinueStatement *node); dvander@195: void visit(IncDecExpression *node); dvander@195: void visit(UnaryExpression *node); dvander@195: void visit(TernaryExpression *node); dvander@195: void visit(StructureStatement *node); dvander@195: void visit(FieldExpression *node); dvander@195: void visit(SwitchStatement *node); dvander@195: void visit(FunctionTypeStatement *node); dvander@195: void visit(ArrayLiteral *node); dvander@195: void visit(ImportStatement *node); dvander@195: }; dvander@195: dvander@195: } dvander@195: dvander@195: #endif // _include_bytecode_generator_h_