1
+ #include < iostream>
2
+ #include < memory>
3
+ #include " binaryen-c.h"
4
+ #include " lexer/Lexemes.hpp"
5
+ #include " StandardLibrary.hpp"
6
+ #include " parser/ast/ASTNodeList.hpp"
7
+ #include " parser/ast/FunctionDeclarationNode.hpp"
8
+ #include " parser/ast/IdentifierNode.hpp"
9
+ #include " parser/ast/TypeDeclarationNode.hpp"
1
10
#include " CodeGen.hpp"
11
+ #include " DataTypes.hpp"
2
12
3
13
namespace Theta {
4
14
BinaryenModuleRef CodeGen::generateWasmFromAST (shared_ptr<ASTNode> ast) {
@@ -10,12 +20,20 @@ namespace Theta {
10
20
11
21
generate (ast, module );
12
22
23
+ BinaryenModuleAutoDrop (module );
24
+
13
25
return module ;
14
26
}
15
27
16
28
BinaryenExpressionRef CodeGen::generate (shared_ptr<ASTNode> node, BinaryenModuleRef &module ) {
17
29
if (node->getNodeType () == ASTNode::SOURCE) {
18
30
generateSource (dynamic_pointer_cast<SourceNode>(node), module );
31
+ } else if (node->getNodeType () == ASTNode::CAPSULE) {
32
+ return generateCapsule (dynamic_pointer_cast<CapsuleNode>(node), module );
33
+ } else if (node->getNodeType () == ASTNode::BLOCK) {
34
+ return generateBlock (dynamic_pointer_cast<ASTNodeList>(node), module );
35
+ } else if (node->getNodeType () == ASTNode::RETURN) {
36
+ return generateReturn (dynamic_pointer_cast<ReturnNode>(node), module );
19
37
} else if (node->getNodeType () == ASTNode::BINARY_OPERATION) {
20
38
return generateBinaryOperation (dynamic_pointer_cast<BinaryOperationNode>(node), module );
21
39
} else if (node->getNodeType () == ASTNode::UNARY_OPERATION) {
@@ -31,6 +49,60 @@ namespace Theta {
31
49
return nullptr ;
32
50
}
33
51
52
+ BinaryenExpressionRef CodeGen::generateCapsule (shared_ptr<CapsuleNode> capsuleNode, BinaryenModuleRef &module ) {
53
+ vector<shared_ptr<ASTNode>> capsuleElements = dynamic_pointer_cast<ASTNodeList>(capsuleNode->getValue ())->getElements ();
54
+
55
+ for (auto elem : capsuleElements) {
56
+ string elemType = dynamic_pointer_cast<TypeDeclarationNode>(elem->getResolvedType ())->getType ();
57
+ if (elem->getNodeType () == ASTNode::ASSIGNMENT) {
58
+ shared_ptr<IdentifierNode> identNode = dynamic_pointer_cast<IdentifierNode>(elem->getLeft ());
59
+
60
+ if (elemType == DataTypes::FUNCTION) {
61
+ shared_ptr<FunctionDeclarationNode> fnDeclNode = dynamic_pointer_cast<FunctionDeclarationNode>(elem->getRight ());
62
+
63
+
64
+ string functionName = capsuleNode->getName () + " ." + identNode->getIdentifier ();
65
+
66
+ cout << " it is" << functionName.c_str () << " " << functionName.c_str () << endl;
67
+
68
+ BinaryenExpressionRef body = generate (fnDeclNode->getDefinition (), module );
69
+
70
+ BinaryenFunctionRef fn = BinaryenAddFunction (
71
+ module ,
72
+ functionName.c_str (),
73
+ BinaryenTypeNone (),
74
+ getBinaryenTypeFromTypeDeclaration (dynamic_pointer_cast<TypeDeclarationNode>(fnDeclNode->getResolvedType ()->getValue ())),
75
+ NULL ,
76
+ 0 ,
77
+ body
78
+ );
79
+
80
+ BinaryenAddFunctionExport (module , functionName.c_str (), functionName.c_str ());
81
+ }
82
+ }
83
+ }
84
+ }
85
+
86
+ BinaryenExpressionRef CodeGen::generateBlock (shared_ptr<ASTNodeList> blockNode, BinaryenModuleRef &module ) {
87
+ BinaryenExpressionRef* blockExpressions = new BinaryenExpressionRef[blockNode->getElements ().size ()];
88
+
89
+ for (int i = 0 ; i < blockNode->getElements ().size (); i++) {
90
+ blockExpressions[i] = generate (blockNode->getElements ().at (i), module );
91
+ }
92
+
93
+ return BinaryenBlock (
94
+ module ,
95
+ NULL ,
96
+ blockExpressions,
97
+ blockNode->getElements ().size (),
98
+ BinaryenTypeNone ()
99
+ );
100
+ }
101
+
102
+ BinaryenExpressionRef CodeGen::generateReturn (shared_ptr<ReturnNode> returnNode, BinaryenModuleRef &module ) {
103
+ return BinaryenReturn (module , generate (returnNode->getValue (), module ));
104
+ }
105
+
34
106
BinaryenExpressionRef CodeGen::generateBinaryOperation (shared_ptr<BinaryOperationNode> binOpNode, BinaryenModuleRef &module ) {
35
107
if (binOpNode->getOperator () == Lexemes::EXPONENT) {
36
108
return generateExponentOperation (binOpNode, module );
@@ -122,24 +194,24 @@ namespace Theta {
122
194
BinaryenExpressionRef body = generate (sourceNode->getValue (), module );
123
195
124
196
if (!body) {
125
- throw std:: runtime_error (" Invalid body type for source node" );
197
+ throw runtime_error (" Invalid body type for source node" );
126
198
}
127
199
200
+ shared_ptr<TypeDeclarationNode> returnType = dynamic_pointer_cast<TypeDeclarationNode>(sourceNode->getValue ()->getResolvedType ());
201
+
128
202
BinaryenFunctionRef mainFn = BinaryenAddFunction (
129
203
module ,
130
204
" main" ,
131
205
BinaryenTypeNone (),
132
- // BinaryenTypeStringref(),
133
- // BinaryenTypeInt64(),
134
- BinaryenTypeInt32 (),
206
+ getBinaryenTypeFromTypeDeclaration (returnType),
135
207
NULL ,
136
208
0 ,
137
209
body
138
210
);
139
211
140
212
BinaryenAddFunctionExport (module , " main" , " main" );
141
213
} else {
142
- // generate(sourceNode->getValue(), module);
214
+ generate (sourceNode->getValue (), module );
143
215
}
144
216
}
145
217
@@ -151,7 +223,24 @@ namespace Theta {
151
223
if (op == Lexemes::TIMES) return BinaryenMulInt64 ();
152
224
if (op == Lexemes::MODULO) return BinaryenRemSInt64 ();
153
225
226
+ string resolvedType = dynamic_pointer_cast<TypeDeclarationNode>(binOpNode->getLeft ()->getResolvedType ())->getType ();
227
+
228
+ if (op == Lexemes::EQUALITY && resolvedType == DataTypes::NUMBER) return BinaryenEqInt64 ();
229
+ if (op == Lexemes::EQUALITY && resolvedType == DataTypes::BOOLEAN) return BinaryenEqInt32 ();
230
+ if (op == Lexemes::EQUALITY && resolvedType == DataTypes::STRING) return BinaryenStringEqEqual ();
231
+ if (op == Lexemes::INEQUALITY && resolvedType == DataTypes::NUMBER) return BinaryenNeInt64 ();
232
+ if (op == Lexemes::INEQUALITY && resolvedType == DataTypes::BOOLEAN) return BinaryenEqInt32 ();
233
+ if (op == Lexemes::INEQUALITY && resolvedType == DataTypes::STRING) return BinaryenStringEqEqual (); // FIXME: This is a stub
234
+ if (op == Lexemes::LT && resolvedType == DataTypes::NUMBER) return BinaryenLtSInt64 ();
235
+ if (op == Lexemes::GT && resolvedType == DataTypes::NUMBER) return BinaryenGtSInt64 ();
236
+
154
237
155
238
// if (op == "**") return
156
239
}
240
+
241
+ BinaryenType CodeGen::getBinaryenTypeFromTypeDeclaration (shared_ptr<TypeDeclarationNode> typeDeclaration) {
242
+ if (typeDeclaration->getType () == DataTypes::NUMBER) return BinaryenTypeInt64 ();
243
+ if (typeDeclaration->getType () == DataTypes::STRING) return BinaryenTypeStringref ();
244
+ if (typeDeclaration->getType () == DataTypes::BOOLEAN) return BinaryenTypeInt32 ();
245
+ }
157
246
}
0 commit comments