Skip to content

Commit d4f5b6a

Browse files
Simplify AST class hierarchy. There was too many useless classes.
1 parent 5a3acb3 commit d4f5b6a

File tree

7 files changed

+471
-699
lines changed

7 files changed

+471
-699
lines changed

ast.cpp

Lines changed: 190 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,170 @@
1212

1313
using namespace std;
1414

15+
//Empty children list constant
16+
const AstNodeList AstNode::ms_noChildren;
17+
18+
// Constructor functions.
19+
//
20+
////////////////////////////////
21+
Ref<AstNode> astCreateBlock(CScriptToken token)
22+
{
23+
return refFromNew( new AstBranchNode(AST_BLOCK, token.getPosition()));
24+
}
25+
26+
Ref<AstNode> astCreateIf (ScriptPosition pos,
27+
Ref<AstNode> condition,
28+
Ref<AstNode> thenSt,
29+
Ref<AstNode> elseSt)
30+
{
31+
32+
auto result = refFromNew( new AstBranchNode(AST_IF, pos));
33+
34+
result->addChild(condition);
35+
result->addChild(thenSt);
36+
result->addChild(elseSt);
37+
38+
return result;
39+
}
40+
41+
Ref<AstNode> astCreateConditional ( ScriptPosition pos,
42+
Ref<AstNode> condition,
43+
Ref<AstNode> thenExpr,
44+
Ref<AstNode> elseExpr)
45+
{
46+
auto result = refFromNew( new AstBranchNode(AST_CONDITIONAL, pos));
47+
48+
result->addChild(condition);
49+
result->addChild(thenExpr);
50+
result->addChild(elseExpr);
51+
52+
return result;
53+
}
54+
55+
Ref<AstNode> astCreateFor (ScriptPosition pos,
56+
Ref<AstNode> initSt,
57+
Ref<AstNode> condition,
58+
Ref<AstNode> incrementSt,
59+
Ref<AstNode> body)
60+
{
61+
auto result = refFromNew( new AstBranchNode(AST_FOR, pos));
62+
63+
result->addChild(initSt);
64+
result->addChild(condition);
65+
result->addChild(incrementSt);
66+
result->addChild(body);
67+
68+
return result;
69+
}
70+
71+
Ref<AstNode> astCreateReturn (ScriptPosition pos, Ref<AstNode> expr)
72+
{
73+
auto result = refFromNew( new AstBranchNode(AST_RETURN, pos));
74+
75+
result->addChild(expr);
76+
return result;
77+
}
78+
79+
Ref<AstNode> astCreateAssignment(ScriptPosition pos,
80+
int opCode,
81+
Ref<AstNode> lexpr,
82+
Ref<AstNode> rexpr)
83+
{
84+
auto result = refFromNew( new AstOperator(AST_ASSIGNMENT, pos, opCode));
85+
86+
result->addChild(lexpr);
87+
result->addChild(rexpr);
88+
return result;
89+
}
90+
91+
Ref<AstNode> astCreatePrefixOp(CScriptToken token, Ref<AstNode> rexpr)
92+
{
93+
auto result = refFromNew( new AstOperator(AST_PREFIXOP,
94+
token.getPosition(),
95+
token.type()));
96+
97+
result->addChild(rexpr);
98+
return result;
99+
}
100+
101+
Ref<AstNode> astCreatePostfixOp(CScriptToken token, Ref<AstNode> lexpr)
102+
{
103+
auto result = refFromNew( new AstOperator(AST_POSTFIXOP,
104+
token.getPosition(),
105+
token.type()));
106+
107+
result->addChild(lexpr);
108+
return result;
109+
}
110+
111+
Ref<AstNode> astCreateBinaryOp(CScriptToken token,
112+
Ref<AstNode> lexpr,
113+
Ref<AstNode> rexpr)
114+
{
115+
auto result = refFromNew( new AstOperator(AST_BINARYOP,
116+
token.getPosition(),
117+
token.type()));
118+
119+
result->addChild(lexpr);
120+
result->addChild(rexpr);
121+
return result;
122+
}
123+
124+
Ref<AstNode> astCreateFnCall(ScriptPosition pos, Ref<AstNode> fnExpr, bool newCall)
125+
{
126+
const AstNodeTypes type = newCall ? AST_NEWCALL: AST_FNCALL;
127+
auto result = refFromNew( new AstBranchNode(type, pos));
128+
129+
result->addChild(fnExpr);
130+
return result;
131+
}
132+
133+
/**
134+
* Transforms a regular function call into a 'new' operator call.
135+
* @param callExpr
136+
* @return
137+
*/
138+
Ref<AstNode> astToNewCall(Ref<AstNode> callExpr)
139+
{
140+
return astCreateFnCall(callExpr->position(),
141+
callExpr->children()[0], true);
142+
}
143+
144+
/**
145+
* Creates an array literal AST node.
146+
* @param pos
147+
* @return
148+
*/
149+
Ref<AstNode> astCreateArray(ScriptPosition pos)
150+
{
151+
return refFromNew( new AstBranchNode(AST_ARRAY, pos));
152+
}
153+
154+
Ref<AstNode> astCreateArrayAccess(ScriptPosition pos,
155+
Ref<AstNode> arrayExpr,
156+
Ref<AstNode> indexExpr)
157+
{
158+
auto result = refFromNew( new AstBranchNode(AST_ARRAY_ACCESS, pos));
159+
160+
result->addChild(arrayExpr);
161+
result->addChild(indexExpr);
162+
163+
return result;
164+
}
165+
166+
Ref<AstNode> astCreateMemberAccess(ScriptPosition pos,
167+
Ref<AstNode> objExpr,
168+
Ref<AstNode> identifier)
169+
{
170+
auto result = refFromNew( new AstBranchNode(AST_MEMBER_ACCESS, pos));
171+
172+
result->addChild(objExpr);
173+
result->addChild(identifier);
174+
175+
return result;
176+
}
177+
178+
15179
/**
16180
* Creates an 'AstLiteral' object from a source token.
17181
* @param token
@@ -56,40 +220,38 @@ Ref<AstLiteral> AstLiteral::create(ScriptPosition pos, int value)
56220
* This particular version creates an object containing all its children
57221
* @return
58222
*/
59-
Ref<JSValue> AstStatement::toJSValue()const
223+
Ref<JSValue> AstNode::toJS()const
60224
{
61225
Ref<JSObject> obj = JSObject::create();
62226

63227
obj->set("a_type", jsString(astTypeToString(getType())));
64-
obj->set("z_children", toJSArray(m_children));
65-
66-
return obj;
67-
}
68228

69-
/**
70-
* Var declaration to JSValue
71-
* @return
72-
*/
73-
Ref<JSValue> AstVar::toJSValue()const
74-
{
75-
Ref<JSObject> obj = AstStatement::toJSValue().staticCast<JSObject>();
76-
77-
obj->set("b_name", jsString(name));
229+
const string name = getName();
230+
if (!name.empty())
231+
obj->set("b_name", jsString(name));
78232

233+
const AstNodeList& c = children();
234+
if (!c.empty())
235+
obj->set("z_children", toJSArray(c));
236+
237+
const auto value = getValue();
238+
if (!value->isUndefined())
239+
obj->set("v_value", value);
240+
79241
return obj;
80242
}
81243

244+
82245
/**
83246
* Function declaration to JSValue
84247
* @return
85248
*/
86-
Ref<JSValue> AstFunction::toJSValue()const
249+
Ref<JSValue> AstFunction::toJS()const
87250
{
88-
Ref<JSObject> obj = AstExpression::toJSValue().staticCast<JSObject>();
251+
Ref<JSObject> obj = AstNode::toJS().staticCast<JSObject>();
89252

90-
obj->set("b_name", jsString(m_name));
91253
obj->set("c_parameters", JSArray::createStrArray(m_params));
92-
obj->set("d_code", m_code->toJSValue());
254+
obj->set("d_code", m_code->toJS());
93255

94256
return obj;
95257
}
@@ -98,67 +260,29 @@ Ref<JSValue> AstFunction::toJSValue()const
98260
* Operator to JSValue
99261
* @return
100262
*/
101-
Ref<JSValue> AstOperator::toJSValue()const
263+
Ref<JSValue> AstOperator::toJS()const
102264
{
103-
Ref<JSObject> obj = AstExpression::toJSValue().staticCast<JSObject>();
265+
Ref<JSObject> obj = AstBranchNode::toJS().staticCast<JSObject>();
104266

105267
obj->set("d_operator", jsString(getTokenStr(code)));
106268
return obj;
107269
}
108270

109-
/**
110-
* Function call to JSValue
111-
* @return
112-
*/
113-
Ref<JSValue> AstFunctionCall::toJSValue()const
114-
{
115-
Ref<JSObject> obj = AstExpression::toJSValue().staticCast<JSObject>();
116-
117-
obj->set("d_isNew", jsBool(m_bNew));
118-
return obj;
119-
}
120-
121-
/**
122-
* Literal to JSValue
123-
* @return
124-
*/
125-
Ref<JSValue> AstLiteral::toJSValue()const
126-
{
127-
Ref<JSObject> obj = JSObject::create();
128-
129-
obj->set("a_type", jsString(astTypeToString(getType())));
130-
obj->set("v_value", value);
131-
return obj;
132-
}
133-
134-
/**
135-
* Identifier to JSValue
136-
* @return
137-
*/
138-
Ref<JSValue> AstIdentifier::toJSValue()const
139-
{
140-
Ref<JSObject> obj = JSObject::create();
141-
142-
obj->set("a_type", jsString(astTypeToString(getType())));
143-
obj->set("b_name", jsString(name));
144-
return obj;
145-
}
146-
147271
/**
148272
* Object literal to JSValue
149273
* @return
150274
*/
151-
Ref<JSValue> AstObject::toJSValue()const
275+
Ref<JSValue> AstObject::toJS()const
152276
{
153277
Ref<JSObject> obj = JSObject::create();
154278
Ref<JSObject> props = JSObject::create();
155279

156280
obj->set("a_type", jsString(astTypeToString(getType())));
157281
obj->set("b_properties", props);
158282

159-
PropsMap::const_iterator it;
283+
PropertyList::const_iterator it;
160284
for (it = m_properties.begin(); it != m_properties.end(); ++it)
161-
props->set(it->first, it->second->toJSValue());
285+
props->set(it->name, it->expr->toJS());
162286

163287
return obj;
164288
}
@@ -174,18 +298,18 @@ Ref<AstLiteral> AstLiteral::undefined(ScriptPosition pos)
174298
}
175299

176300
/**
177-
* Transforms a list of AstStatements into a Javascript Array.
301+
* Transforms a list of AstNodes into a Javascript Array.
178302
* @param statements
179303
* @return
180304
*/
181-
Ref<JSArray> toJSArray (const StatementList& statements)
305+
Ref<JSArray> toJSArray (const AstNodeList& statements)
182306
{
183307
Ref<JSArray> result = JSArray::create();
184308

185309
for (size_t i = 0; i < statements.size(); ++i)
186310
{
187311
if (statements[i].notNull())
188-
result->push( statements[i]->toJSValue() );
312+
result->push( statements[i]->toJS() );
189313
else
190314
result->push(jsNull());
191315
}
@@ -198,7 +322,7 @@ Ref<JSArray> toJSArray (const StatementList& statements)
198322
* @param statements
199323
* @return
200324
*/
201-
std::string toJSON (const StatementList& statements)
325+
std::string toJSON (const AstNodeList& statements)
202326
{
203327
return toJSArray(statements)->getJSON(0);
204328
}
@@ -223,6 +347,7 @@ std::string astTypeToString(AstNodeTypes type)
223347
types[AST_FUNCTION] = "AST_FUNCTION";
224348
types[AST_ASSIGNMENT] = "AST_ASSIGNMENT";
225349
types[AST_FNCALL] = "AST_FNCALL";
350+
types[AST_NEWCALL] = "AST_NEWCALL";
226351
types[AST_LITERAL] = "AST_LITERAL";
227352
types[AST_IDENTIFIER] = "AST_IDENTIFIER";
228353
types[AST_ARRAY] = "AST_ARRAY";

0 commit comments

Comments
 (0)