Skip to content

Commit 2d99761

Browse files
committed
feat: capsule level variable declarations
1 parent 85f1e79 commit 2d99761

File tree

1 file changed

+30
-2
lines changed

1 file changed

+30
-2
lines changed

src/compiler/CodeGen.cpp

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
#include "CodeGen.hpp"
1010
#include "DataTypes.hpp"
1111
#include "parser/ast/AssignmentNode.hpp"
12+
#include "parser/ast/IdentifierNode.hpp"
13+
#include "parser/ast/TypeDeclarationNode.hpp"
1214

1315
namespace Theta {
1416
BinaryenModuleRef CodeGen::generateWasmFromAST(shared_ptr<ASTNode> ast) {
@@ -67,15 +69,25 @@ namespace Theta {
6769
for (auto elem : capsuleElements) {
6870
string elemType = dynamic_pointer_cast<TypeDeclarationNode>(elem->getResolvedType())->getType();
6971
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();
7173

7274
if (elemType == DataTypes::FUNCTION) {
7375
generateFunctionDeclaration(
74-
identNode->getIdentifier(),
76+
identifier,
7577
dynamic_pointer_cast<FunctionDeclarationNode>(elem->getRight()),
7678
module,
7779
true
7880
);
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+
);
7991
}
8092
}
8193
}
@@ -84,6 +96,12 @@ namespace Theta {
8496
BinaryenExpressionRef CodeGen::generateAssignment(shared_ptr<AssignmentNode> assignmentNode, BinaryenModuleRef &module) {
8597
string assignmentIdentifier = dynamic_pointer_cast<IdentifierNode>(assignmentNode->getLeft())->getIdentifier();
8698

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.
87105
if (assignmentNode->getRight()->getNodeType() != ASTNode::FUNCTION_DECLARATION) {
88106
// 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
89107
// local idx
@@ -213,6 +231,16 @@ namespace Theta {
213231
BinaryenExpressionRef CodeGen::generateIdentifier(shared_ptr<IdentifierNode> identNode, BinaryenModuleRef &module) {
214232
shared_ptr<ASTNode> identInScope = scope.lookup(identNode->getIdentifier());
215233

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+
216244
return BinaryenLocalGet(
217245
module,
218246
identInScope->getMappedBinaryenIndex(),

0 commit comments

Comments
 (0)