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