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"
15 ScopeBuilder::nextId()
18 ss
<< "global_$" << ++nextId_
;
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
= "@";
29 ctx
.parent
= node
.scope
;
30 browseFile
<ScopeBuilder
>(node
, ctx
);
34 static void visitFunctionDecl(ast::Node
& node_
, ScopeBuilder
& ctx
)
36 auto & node
= reinterpret_cast<ast::FunctionDecl
&> (node_
);
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
;
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_
);
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
;
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
)
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(),
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_
);
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
;
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_
);
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
;
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
;
172 ast::CastExpPtr cast
= new ast::CastExp
;
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_
);
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_
);
196 ctx
.parent
->addType(node
.name
, node
.type
);
199 ScopeBuilder::ScopeBuilder()
200 : Visitor
<ScopeBuilder
>(),
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
> >();