9
9
#include " CodeGen.hpp"
10
10
#include " DataTypes.hpp"
11
11
#include " parser/ast/AssignmentNode.hpp"
12
+ #include " parser/ast/IdentifierNode.hpp"
13
+ #include " parser/ast/TypeDeclarationNode.hpp"
12
14
13
15
namespace Theta {
14
16
BinaryenModuleRef CodeGen::generateWasmFromAST (shared_ptr<ASTNode> ast) {
@@ -67,15 +69,25 @@ namespace Theta {
67
69
for (auto elem : capsuleElements) {
68
70
string elemType = dynamic_pointer_cast<TypeDeclarationNode>(elem->getResolvedType ())->getType ();
69
71
if (elem->getNodeType () == ASTNode::ASSIGNMENT) {
70
- shared_ptr<IdentifierNode> identNode = dynamic_pointer_cast<IdentifierNode>(elem->getLeft ());
72
+ string identifier = dynamic_pointer_cast<IdentifierNode>(elem->getLeft ())-> getIdentifier ( );
71
73
72
74
if (elemType == DataTypes::FUNCTION) {
73
75
generateFunctionDeclaration (
74
- identNode-> getIdentifier () ,
76
+ identifier ,
75
77
dynamic_pointer_cast<FunctionDeclarationNode>(elem->getRight ()),
76
78
module ,
77
79
true
78
80
);
81
+ } else {
82
+ shared_ptr<ASTNode> assignmentRhs = elem->getRight ();
83
+ assignmentRhs->setMappedBinaryenIndex (-1 ); // Index of -1 means its a global
84
+ scope.insert (identifier, assignmentRhs);
85
+
86
+ BinaryenGlobalSet (
87
+ module ,
88
+ identifier.c_str (),
89
+ generate (assignmentRhs, module )
90
+ );
79
91
}
80
92
}
81
93
}
@@ -84,6 +96,12 @@ namespace Theta {
84
96
BinaryenExpressionRef CodeGen::generateAssignment (shared_ptr<AssignmentNode> assignmentNode, BinaryenModuleRef &module ) {
85
97
string assignmentIdentifier = dynamic_pointer_cast<IdentifierNode>(assignmentNode->getLeft ())->getIdentifier ();
86
98
99
+ // Function declarations dont get generated generically like the rest of the AST elements, they are not part of the "generate" method,
100
+ // because they behave differently depending on where the function was declared. A function declared at the top level of capsule will
101
+ // be hoisted and will have no inherent scope bound to it.
102
+ //
103
+ // A function declared within another function body OR within any other structure will be turned into a closure that contains the scope
104
+ // of anything outside of that function.
87
105
if (assignmentNode->getRight ()->getNodeType () != ASTNode::FUNCTION_DECLARATION) {
88
106
// Using a space in scope for an idx counter so we dont have to have a whole separate stack just to keep track of the current
89
107
// local idx
@@ -213,6 +231,16 @@ namespace Theta {
213
231
BinaryenExpressionRef CodeGen::generateIdentifier (shared_ptr<IdentifierNode> identNode, BinaryenModuleRef &module ) {
214
232
shared_ptr<ASTNode> identInScope = scope.lookup (identNode->getIdentifier ());
215
233
234
+ if (identInScope->getMappedBinaryenIndex () == -1 ) {
235
+ string identName = identNode->getIdentifier ();
236
+
237
+ return BinaryenGlobalGet (
238
+ module ,
239
+ identName.c_str (),
240
+ getBinaryenTypeFromTypeDeclaration (dynamic_pointer_cast<TypeDeclarationNode>(identInScope->getResolvedType ()))
241
+ );
242
+ }
243
+
216
244
return BinaryenLocalGet (
217
245
module ,
218
246
identInScope->getMappedBinaryenIndex (),
0 commit comments