[moulette] switched to boost::signals2
[ozulis.git] / src / ozulis / visitors / scope-builder.cc
bloba34fe7980ecb136fa3daaecb3a888505c54d662a
1 #include <sstream>
2 #include <boost/foreach.hpp>
4 #include <ozulis/core/assert.hh>
5 #include <ozulis/ast/ast.hh>
6 #include <ozulis/ast/node-factory.hh>
7 #include <ozulis/visitors/browser.hh>
8 #include "scope-builder.hh"
10 namespace ozulis
12 namespace visitors
14 std::string
15 ScopeBuilder::nextId()
17 std::stringstream ss;
18 ss << "global_$" << ++nextId_;
19 return ss.str();
22 static void visitFile(ast::Node & node_, ScopeBuilder & ctx)
24 auto & node = reinterpret_cast<ast::File &> (node_);
25 node.scope = new ast::Scope();
26 node.scope->parent = 0;
27 node.scope->prefix = "@";
28 ctx.file = &node;
29 ctx.parent = node.scope;
30 browseFile<ScopeBuilder>(node, ctx);
31 ctx.parent = 0;
34 static void visitFunctionDecl(ast::Node & node_, ScopeBuilder & ctx)
36 auto & node = reinterpret_cast<ast::FunctionDecl &> (node_);
37 assert(ctx.parent);
38 assert(node.args);
40 ast::FunctionTypePtr ftype = new ast::FunctionType;
41 ftype->type = node.returnType;
42 ftype->argsType = new std::vector<ast::TypePtr> ();
43 BOOST_FOREACH (ast::VarDecl * varDecl, *node.args)
44 ftype->argsType->push_back(varDecl->type);
46 ast::SymbolPtr symbol = new ast::Symbol;
47 symbol->name = node.name;
48 symbol->type = ftype;
49 symbol->address = new ast::MemoryAddress;
50 ctx.parent->addSymbol(symbol);
53 void visitFunction(ast::Node & node_, ScopeBuilder & ctx)
55 auto & node = reinterpret_cast<ast::Function &> (node_);
57 assert(ctx.parent);
58 assert(node.block);
59 assert(node.args);
61 ast::FunctionTypePtr ftype = new ast::FunctionType;
62 ftype->type = node.returnType;
63 ftype->argsType = new std::vector<ast::TypePtr> ();
64 BOOST_FOREACH (ast::VarDecl * varDecl, *node.args)
65 ftype->argsType->push_back(varDecl->type);
67 ast::SymbolPtr symbol = new ast::Symbol;
68 symbol->name = node.name;
69 symbol->type = ftype;
70 symbol->address = new ast::MemoryAddress;
71 /// @todo address suffix
72 ctx.parent->addSymbol(symbol);
74 node.scope = new ast::Scope;
75 node.scope->parent = ctx.parent;
76 node.scope->prefix = "%";
78 BOOST_FOREACH (ast::VarDeclPtr & varDecl, *node.args)
80 assert(varDecl);
82 symbol = new ast::Symbol;
83 symbol->name = "." + varDecl->name;
84 symbol->address = new ast::RegisterAddress;
85 symbol->type = varDecl->type;
86 node.scope->addSymbol(symbol);
88 ast::SymbolExpPtr value = new ast::SymbolExp;
89 value->symbol = symbol;
91 ast::ValuedVarDeclPtr valuedVarDecl = new ast::ValuedVarDecl;
92 valuedVarDecl->name = varDecl->name;
93 valuedVarDecl->type = varDecl->type;
94 valuedVarDecl->value = value;
96 node.block->varDecls->insert(node.block->varDecls->begin(),
97 valuedVarDecl);
100 ctx.parent = node.scope;
101 ctx.blockIds.clear();
102 ctx.blockIds.push_back(0);
103 ScopeBuilder::visit(*node.block, ctx);
104 ctx.parent = node.scope->parent;
107 void visitBlock(ast::Node & node_, ScopeBuilder & ctx)
109 auto & node = reinterpret_cast<ast::Block &> (node_);
110 assert(ctx.parent);
111 node.scope = new ast::Scope();
112 node.scope->parent = ctx.parent;
114 std::stringstream stream;
115 stream << ctx.parent->prefix << ".B" << ctx.blockIds.back()++ << ".";
116 node.scope->prefix = stream.str();
117 ctx.parent = node.scope;
119 assert(node.varDecls);
120 BOOST_FOREACH (ast::VarDeclPtr & varDecl, (*node.varDecls))
122 ast::SymbolPtr symbol = new ast::Symbol;
124 assert(varDecl);
125 symbol->name = varDecl->name;
126 ast::ReferenceTypePtr rtype = new ast::ReferenceType;
127 rtype->type = varDecl->type;
128 symbol->type = rtype;
129 ast::MemoryAddressPtr addr = new ast::MemoryAddress;
130 symbol->address = addr;
131 node.scope->addSymbol(symbol);
134 ctx.blockIds.push_back(0);
135 browseBlock<ScopeBuilder>(node, ctx);
136 ctx.blockIds.pop_back();
137 ctx.parent = node.scope->parent;
140 /// @todo check this one again later
141 static void visitStringExp(ast::Node & node_, ScopeBuilder & ctx)
143 auto & node = reinterpret_cast<ast::StringExp &> (node_);
144 assert(ctx.file);
146 ast::ArrayTypePtr array = new ast::ArrayType;
147 array->isConst = true;
148 array->size = node.string.length() + 1;
149 array->type = ast::NodeFactory::createIntegerType(false, 8);
151 ast::ReferenceTypePtr rtype = new ast::ReferenceType;
152 rtype->type = array;
154 ast::ValuedVarDeclPtr varDecl = new ast::ValuedVarDecl;
155 varDecl->name = ctx.file->scope->nextStringId();
156 varDecl->type = rtype;
157 varDecl->value = &node;
158 node.type = varDecl->type;
160 ast::SymbolPtr symbol = new ast::Symbol;
161 symbol->name = varDecl->name;
162 symbol->type = varDecl->type;
163 symbol->address = ast::NodeFactory::createMemoryAddress();
165 ast::SymbolExpPtr sexp = new ast::SymbolExp;
166 sexp->symbol = symbol;
167 sexp->type = symbol->type;
169 ast::AtExpPtr at = new ast::AtExp;
170 at->exp = sexp;
172 ast::CastExpPtr cast = new ast::CastExp;
173 cast->exp = at;
174 cast->type = ast::NodeFactory::createConstStringType();
176 assert(&node == *ctx.parentRef);
177 *ctx.parentRef = cast;
179 ctx.file->scope->addSymbol(symbol);
180 ctx.file->varDecls->push_back(varDecl);
183 static void visitAlias(ast::Node & node_, ScopeBuilder & ctx)
185 auto & node = reinterpret_cast<ast::Alias &> (node_);
186 assert(ctx.parent);
188 ctx.parent->addType(node.name, node.type);
191 static void visitTypedef(ast::Node & node_, ScopeBuilder & ctx)
193 auto & node = reinterpret_cast<ast::Typedef &> (node_);
194 assert(ctx.parent);
196 ctx.parent->addType(node.name, node.type);
199 ScopeBuilder::ScopeBuilder()
200 : Visitor<ScopeBuilder>(),
201 file(0),
202 parent(0),
203 nextId_(0)
207 void
208 ScopeBuilder::initBase()
210 #define REGISTER_METHOD(Class) \
211 registerMethod(ast::Class::nodeTypeId(), visit##Class)
213 REGISTER_METHOD(File);
214 REGISTER_METHOD(Function);
215 REGISTER_METHOD(FunctionDecl);
216 REGISTER_METHOD(Block);
217 REGISTER_METHOD(StringExp);
218 REGISTER_METHOD(Alias);
219 REGISTER_METHOD(Typedef);
221 completeWith<Browser<ScopeBuilder> >();