[visitors] ported llvm asm generator
[ozulis.git] / src / ozulis / visitors / scope-builder.cc
blob38d09a1ad311409faf9df137a28f349b4882dab4
1 #include <sstream>
2 #include <boost/foreach.hpp>
4 #include <ozulis/core/assert.hh>
5 #include <ozulis/visitors/browser.hh>
6 #include "scope-builder.hh"
8 namespace ozulis
10 namespace visitors
12 std::string
13 ScopeBuilder::nextId()
15 std::stringstream ss;
16 ss << "global_$" << ++nextId_;
17 return ss.str();
20 static void visitFile(ast::Node & node_, ScopeBuilder & ctx)
22 ast::File & node = reinterpret_cast<ast::File &> (node_);
23 node.scope = new ast::Scope();
24 node.scope->setParent(ctx.parent);
25 ctx.global = node.scope;
26 ctx.parent = node.scope;
27 browseFile<ScopeBuilder>(node, ctx);
28 ctx.parent = node.scope->parent();
31 static void visitFunctionDecl(ast::Node & node_, ScopeBuilder & ctx)
33 ast::FunctionDecl & node = reinterpret_cast<ast::FunctionDecl &> (node_);
34 assert(ctx.parent);
35 assert(node.args);
37 ast::FunctionType *ftype = new ast::FunctionType;
38 ftype->returnType = node.returnType;
39 ftype->argsType = new std::vector<ast::Type *> ();
40 BOOST_FOREACH (ast::VarDecl * varDecl, *node.args)
41 ftype->argsType->push_back(varDecl->type);
43 ast::Symbol * symbol = new ast::Symbol;
44 symbol->name = node.name;
45 symbol->type = ftype;
46 symbol->address = new ast::MemoryAddress;
47 ctx.parent->addSymbol(symbol);
50 void visitFunction(ast::Node & node_, ScopeBuilder & ctx)
52 ast::Function & node = reinterpret_cast<ast::Function &> (node_);
54 assert(ctx.parent);
55 assert(node.block);
56 assert(node.args);
58 ast::FunctionType *ftype = new ast::FunctionType;
59 ftype->returnType = node.returnType;
60 ftype->argsType = new std::vector<ast::Type *> ();
61 BOOST_FOREACH (ast::VarDecl * varDecl, *node.args)
62 ftype->argsType->push_back(varDecl->type);
64 ast::Symbol * symbol = new ast::Symbol;
65 symbol->name = node.name;
66 symbol->type = ftype;
67 symbol->address = new ast::MemoryAddress;
68 ctx.parent->addSymbol(symbol);
70 node.scope = new ast::Scope;
71 node.scope->setParent(ctx.parent);
73 BOOST_FOREACH (ast::VarDecl * varDecl, *node.args)
75 symbol = new ast::Symbol;
77 assert(varDecl);
78 symbol->name = varDecl->name;
79 ast::ReferenceType * rtype = new ast::ReferenceType;
80 rtype->type = varDecl->type;
81 symbol->type = rtype;
82 symbol->address = new ast::MemoryAddress;
83 node.scope->addSymbol(symbol);
86 ctx.parent = node.scope;
87 ScopeBuilder::visit(*node.block, ctx);
88 ctx.parent = node.scope->parent();
91 void visitBlock(ast::Node & node_, ScopeBuilder & ctx)
93 ast::Block & node = reinterpret_cast<ast::Block &> (node_);
94 assert(ctx.parent);
95 node.scope = new ast::Scope();
96 node.scope->setParent(ctx.parent);
97 ctx.parent = node.scope;
99 /// @todo fill the scope with the declarated variables
100 assert(node.varDecls);
101 BOOST_FOREACH (ast::VarDecl * varDecl, (*node.varDecls))
103 ast::Symbol * symbol = new ast::Symbol;
105 assert(varDecl);
106 symbol->name = varDecl->name;
107 ast::ReferenceType * rtype = new ast::ReferenceType;
108 rtype->type = varDecl->type;
109 symbol->type = rtype;
110 symbol->address = new ast::MemoryAddress;
111 node.scope->addSymbol(symbol);
114 browseBlock<ScopeBuilder>(node, ctx);
115 ctx.parent = node.scope->parent();
118 // void
119 // ScopeBuilderVisitor::visit(StringExp & /*node*/)
120 // {
121 // assert(global_);
122 // assert(false);
123 // /// @todo create a global variable
124 // std::string name = nextId();
125 // }
127 ScopeBuilder::ScopeBuilder()
128 : Visitor<ScopeBuilder>(),
129 global(0),
130 parent(0),
131 nextId_(0)
135 void
136 ScopeBuilder::initBase()
138 #define REGISTER_METHOD(Class) \
139 registerMethod(ast::Class::nodeTypeId(), visit##Class)
141 REGISTER_METHOD(File);
142 REGISTER_METHOD(Function);
143 REGISTER_METHOD(FunctionDecl);
144 REGISTER_METHOD(Block);
146 completeWith<Browser<ScopeBuilder> >();