]> git.bts.cx Git - sun.git/blob - runtime/src/sun/compiler/vm_generator.c
do not evaluate variables until they are used
[sun.git] / runtime / src / sun / compiler / vm_generator.c
1 #include "vm_generator.h"
2
3 #include <sun/tree/node_internal.h>
4 #include <sun/tree/node_type.h>
5 #include <sun/tree/tree.h>
6 #include <sun/vm/instruction.h>
7 #include <sun/vm/vm_internal.h>
8
9
10 #include <stdarg.h> //fixme
11 #include <stdbool.h> //fixme
12 #include <stdlib.h> //fixme
13 #include <stdio.h> //fixme
14 #include <string.h> //fixme
15
16 #define generator_assert_msg(t,m,...) if(!(t)) { fprintf(stderr,"%s:%u ERROR:"m"\n",__FILE__,__LINE__, ##__VA_ARGS__); exit(1); }
17 #define generator_assert(t) generator_assert_msg(t,"invalid")
18
19 struct VMGeneratorInstruction {
20 SVMInstruction instruction;
21 };
22
23 struct VMGeneratorOutputScope {
24 char *stringClump;
25 size_t stringClumpSize;
26 size_t stringClumpMaxSize;
27
28 struct VMGeneratorInstruction *instructions;
29 size_t instructionCount;
30 SVMPointer nextInstructionIdx;
31
32 struct VMGeneratorInstruction *resolvableDefinition;
33 };
34 typedef struct VMGeneratorOutputScope VMGeneratorOutputScope;
35
36 enum VMNodeMetadataIdentifierType {
37 VMNodeMetadataIdentifierTypeUnknown,
38 VMNodeMetadataIdentifierTypeNullType,
39 VMNodeMetadataIdentifierTypeIntegerType,
40 VMNodeMetadataIdentifierTypeFloatType,
41 VMNodeMetadataIdentifierTypeStringType,
42 //VMNodeMetadataIdentifierTypeUserType,
43 VMNodeMetadataIdentifierTypeVariable,
44 VMNodeMetadataIdentifierTypeFunction,
45 VMNodeMetadataIdentifierTypeParameter,
46 };
47 typedef enum VMNodeMetadataIdentifierType VMNodeMetadataIdentifierType;
48
49 struct VMNodeMetadata {
50 struct {
51 bool definesScope;
52 bool holdsVariableScope;
53 SLTNode *parentScope;
54 SLTNode *scopedFunctionsHead;
55 SLTNode *scopedVariablesHead;
56 SLTNode *scopedParametersHead;
57 SLTNode *scopedBreaksHead;
58 } scope;
59
60 struct {
61 SVMPointer address;
62 SLTNode *scopedFunctionNext;
63 } function;
64
65 struct {
66 SLTNode *scopedVariableNext;
67 } variable;
68
69 struct {
70 SLTNode *scopedParameterNext;
71 } parameter;
72
73 struct {
74 SVMPointer breakInstruction;
75 SLTNode *scopedBreakNext;
76 } breakStatement;
77
78 struct {
79 VMNodeMetadataIdentifierType type;
80 SLTNode *resolvedNode;
81 } identifier;
82
83 struct {
84 SVMStackOffset offset;
85 } stack;
86
87 struct {
88 SVMPointer address;
89 } string;
90
91 struct {
92 bool native;
93 SVMPointer instruction;
94 } functionCall;
95 };
96 typedef struct VMNodeMetadata VMNodeMetadata;
97
98 union VMGeneratorVisitor {
99 VMGeneratorOutputScope *generator;
100 SLTNode *currentScope;
101 struct {
102 bool typeChanged;
103 bool typeUnresolved;
104 };
105 };
106 typedef union VMGeneratorVisitor VMGeneratorVisitor;
107
108
109 #define sltGetNodeMetadata(node) ((VMNodeMetadata *)(node)->metadata)
110
111
112
113 static VMGeneratorOutputScope *generatorCreate() {
114 VMGeneratorOutputScope *scope = malloc(sizeof(VMGeneratorOutputScope)); // fixme these mallocs
115 memset(scope, 0, sizeof(VMGeneratorOutputScope));
116
117 scope->instructionCount = 2048;
118 scope->instructions = malloc(scope->instructionCount * sizeof(struct VMGeneratorInstruction));
119 scope->nextInstructionIdx = 0;
120
121 scope->stringClumpMaxSize = 1024;
122 scope->stringClump = malloc(scope->stringClumpMaxSize);
123 scope->stringClumpSize = 0;
124
125 return scope;
126 }
127
128
129
130 static size_t opcodeOperandCount(SVMOpcode opcode) {
131 switch (opcode) {
132 case SVMOpcodeSLEEP:
133 case SVMOpcodePOPJUMP:
134 return 0;
135
136 case SVMOpcodeSTK:
137 case SVMOpcodeJUMP:
138 case SVMOpcodePUSHJUMP:
139 return 1;
140
141 case SVMOpcodeMOV:
142 case SVMOpcodeSET:
143 case SVMOpcodeINV:
144 case SVMOpcodeBNOT:
145 case SVMOpcodeNOT:
146 case SVMOpcodeJT:
147 case SVMOpcodeCALL:
148 return 2;
149
150 case SVMOpcodeADD:
151 case SVMOpcodeSUB:
152 case SVMOpcodeMUL:
153 case SVMOpcodeDIV:
154 case SVMOpcodeMOD:
155 case SVMOpcodeBAND:
156 case SVMOpcodeBOR:
157 case SVMOpcodeBXOR:
158 case SVMOpcodeAND:
159 case SVMOpcodeOR:
160 case SVMOpcodeEQ:
161 case SVMOpcodeNEQ:
162 case SVMOpcodeLT:
163 case SVMOpcodeLTEQ:
164 case SVMOpcodeGT:
165 case SVMOpcodeGTEQ:
166 return 3;
167
168 default:
169 generator_assert_msg(false, "invalid opcode %u", opcode);
170 return -1;
171 }
172 }
173
174
175 static SVMPointer generatorNextInstruction(VMGeneratorOutputScope *generator) {
176 generator_assert(generator->nextInstructionIdx < generator->instructionCount);
177 SVMPointer idx = generator->nextInstructionIdx;
178 return idx;
179 }
180
181 static SVMPointer generatorAddInstruction(VMGeneratorOutputScope *generator, SVMOpcode opcode, ...) {
182 generator_assert(generator->nextInstructionIdx < generator->instructionCount);
183
184 SVMPointer idx = generatorNextInstruction(generator);
185 generator->nextInstructionIdx++;
186 struct VMGeneratorInstruction *instruction = &generator->instructions[idx];
187
188 instruction->instruction.opcode = opcode;
189
190 size_t numOperands = opcodeOperandCount(opcode);
191
192 va_list args;
193 va_start(args, opcode);
194 for (size_t i = 0; i < numOperands; ++i) {
195 instruction->instruction.operands[i] = va_arg(args, SVMOperand);
196 }
197 va_end(args);
198
199 return idx;
200 }
201
202 static void generatorPatchOperand(VMGeneratorOutputScope *generator, SVMPointer instruction, size_t idx, SVMOperand value) {
203 generator_assert(instruction < generator->instructionCount);
204 generator_assert_msg(idx < opcodeOperandCount(generator->instructions[instruction].instruction.opcode), "invalid idx");
205 generator->instructions[instruction].instruction.operands[idx] = value;
206 }
207
208 static SVMPointer generatorAddString(VMGeneratorOutputScope *generator, const char *string) {
209 char *ptr = generator->stringClump;
210
211 while (ptr < generator->stringClump + generator->stringClumpSize) {
212 //printf("testing string: %s == %s\n", ptr, string);
213 if (strcmp(string, ptr) == 0) {
214 return ptr - generator->stringClump;
215 }
216 ptr+=strlen(ptr) + 1;
217 }
218
219 size_t stringLength = strlen(string) + 1;
220 generator_assert_msg(ptr + stringLength <= generator->stringClump + generator->stringClumpMaxSize, "out of string space!!!");
221
222 strcpy(ptr, string);
223 generator->stringClumpSize += stringLength;
224
225 //printf("added string: %s\n", string);
226
227 return ptr - generator->stringClump;
228 }
229
230 static SVMStackOffset generatorResolveIdentifier(VMGeneratorOutputScope *generator, SLTNode *node) {
231 VMNodeMetadata *metadata = sltGetNodeMetadata(node);
232 generator_assert_msg(metadata->identifier.type != VMNodeMetadataIdentifierTypeUnknown, "could not resolve %s", node->identifierStringValue);
233 SVMStackOffset offset = sltGetNodeMetadata(metadata->identifier.resolvedNode)->stack.offset;
234 return offset;
235 }
236
237
238 static SVMModule *generatorFinalize(VMGeneratorOutputScope *generator) {
239 size_t memorySize = sizeof(SVMModule) + generator->stringClumpSize + /*0 * sizeof(SVMModuleFunctionDetails) +*/ generator->nextInstructionIdx * sizeof(SVMInstruction);
240
241 SVMModule *module = (SVMModule *)malloc(memorySize);
242 module->header[0] = 's';
243 module->header[1] = 'u';
244 module->header[2] = 'n';
245 module->header[3] = 'l';
246 module->magic = 1525;
247 module->stringBlobLength = generator->stringClumpSize;
248 module->numFunctions = 0; // FIXME
249 module->numInstructions = generator->nextInstructionIdx;
250
251 memcpy((void *)module + sizeof(SVMModule), generator->stringClump, module->stringBlobLength);
252 // COPY FUNCTIONS HERE...
253 memcpy((void *)module + sizeof(SVMModule) + module->stringBlobLength, generator->instructions, module->numInstructions * sizeof(SVMInstruction));
254
255 return module;
256 }
257
258
259
260
261 static void addNodeMetadata(SLTNode *node, void *userParameter) {
262 VMNodeMetadata *metadata = (VMNodeMetadata *)malloc(sizeof(VMNodeMetadata));// fixme
263 memset(metadata, 0, sizeof(VMNodeMetadata));
264 node->metadata = metadata;
265 }
266
267
268 static void findStrings(SLTNode *node, void *userParameter) {
269 VMGeneratorVisitor *visitor = (VMGeneratorVisitor *)userParameter;
270 VMNodeMetadata *metadata = sltGetNodeMetadata(node);
271
272 switch (node->type) {
273 case SLTNodeTypeString:
274 metadata->string.address = generatorAddString(visitor->generator, node->stringValue);
275 break;
276
277 case SLTNodeTypeFunctionCall:
278 metadata->string.address = generatorAddString(visitor->generator, node->functionCallFunction->identifierStringValue);
279 break;
280
281 default:
282 /* do nothing */
283 break;
284 }
285 }
286
287 static bool nodeTypeDefinesScope(SLTNodeType type) {
288 switch (type) {
289 case SLTNodeTypeModule:
290 case SLTNodeTypeFunctionDefinition:
291 case SLTNodeTypeTypeDefinition:
292 case SLTNodeTypeForIteration:
293 case SLTNodeTypeDoIteration:
294 case SLTNodeTypeWhileIteration:
295 case SLTNodeTypeStatementBlock:
296 return true;
297
298 default:
299 return false;
300 }
301 }
302
303 static bool nodeTypeHoldsVariables(SLTNodeType type) {
304 switch (type) {
305 case SLTNodeTypeModule:
306 case SLTNodeTypeFunctionDefinition:
307 return true;
308
309 default:
310 return false;
311 }
312 }
313
314 static void beginScopeNode(SLTNode *node, void *userParameter) {
315 VMGeneratorVisitor *visitor = (VMGeneratorVisitor *)userParameter;
316 VMNodeMetadata *metadata = sltGetNodeMetadata(node);
317
318 metadata->scope.parentScope = visitor->currentScope;
319
320 if (nodeTypeDefinesScope(node->type)) {
321 metadata->scope.definesScope = true;
322 metadata->scope.holdsVariableScope = nodeTypeHoldsVariables(node->type);
323 visitor->currentScope = node;
324 }
325 }
326
327 static void endScopeNode(SLTNode *node, void *userParameter) {
328 VMGeneratorVisitor *visitor = (VMGeneratorVisitor *)userParameter;
329 VMNodeMetadata *metadata = sltGetNodeMetadata(node);
330
331 if (nodeTypeDefinesScope(node->type)) {
332 visitor->currentScope = metadata->scope.parentScope;
333 }
334 }
335
336 static SLTNode *findScope(SLTNode *node) {
337 while (sltGetNodeMetadata(node)->scope.definesScope == false) {
338 VMNodeMetadata *metadata = sltGetNodeMetadata(node);
339 node = metadata->scope.parentScope;
340 generator_assert_msg(node != NULL, "failed to scope"); // FIXME
341 }
342
343 return node;
344 }
345
346 static SLTNode *findContainingScope(SLTNode *node) {
347 for (;;) {
348 node = findScope(node);
349
350 VMNodeMetadata *metadata = sltGetNodeMetadata(node);
351 if (metadata->scope.holdsVariableScope) {
352 return node;
353 }
354
355 node = metadata->scope.parentScope;
356
357 generator_assert_msg(node != NULL, "failed to scope"); // FIXME
358 }
359 }
360
361 static void scopeDefinitions(SLTNode *node, void *userParameter) {
362 VMGeneratorVisitor *visitor = (VMGeneratorVisitor *)userParameter;
363 VMNodeMetadata *metadata = sltGetNodeMetadata(node);
364
365 switch (node->type) {
366 case SLTNodeTypeFunctionParameterDefinition: {
367 //printf("def parameter %s\n", node->functionParameterDefinitionIdentifier->stringValue);
368 VMNodeMetadata *scopeMetadata = sltGetNodeMetadata(findContainingScope(node));
369 metadata->parameter.scopedParameterNext = scopeMetadata->scope.scopedParametersHead;
370 scopeMetadata->scope.scopedParametersHead = node;
371 break;
372 }
373
374 case SLTNodeTypeVariableDefinition: {
375 //printf("def var %s\n", node->variableDefinitionIdentifier->stringValue);
376 VMNodeMetadata *scopeMetadata = sltGetNodeMetadata(findContainingScope(node));
377 metadata->variable.scopedVariableNext = scopeMetadata->scope.scopedVariablesHead;
378 scopeMetadata->scope.scopedVariablesHead = node;
379 break;
380 }
381
382 case SLTNodeTypeFunctionDefinition: {
383 //printf("def func %s\n", node->functionDefinitionIdentifier->stringValue);
384 VMNodeMetadata *scopeMetadata = sltGetNodeMetadata(findScope((sltGetNodeMetadata(findScope(node))->scope.parentScope))); // Functions define a scope...
385 metadata->function.scopedFunctionNext = scopeMetadata->scope.scopedFunctionsHead;
386 scopeMetadata->scope.scopedFunctionsHead = node;
387 break;
388 }
389
390 default:
391 break;
392 }
393 }
394
395 static SLTNode *resolveDefinition(VMNodeMetadataIdentifierType *typeOut, SLTNode *node, const char *name) {
396 if (strcmp(name, "void") == 0) { // FIXME, can de-duplicate these for speed earlier..
397 *typeOut = VMNodeMetadataIdentifierTypeNullType;
398 return NULL;
399 }
400
401 if (strcmp(name, "int") == 0) {
402 *typeOut = VMNodeMetadataIdentifierTypeIntegerType;
403 return NULL;
404 }
405
406 if (strcmp(name, "float") == 0) {
407 *typeOut = VMNodeMetadataIdentifierTypeFloatType;
408 return NULL;
409 }
410
411 if (strcmp(name, "string") == 0) {
412 *typeOut = VMNodeMetadataIdentifierTypeStringType;
413 return NULL;
414 }
415
416 for (;;) {
417 VMNodeMetadata *scopeMetadata = sltGetNodeMetadata(findScope(node));
418
419 // Should do types here...
420
421 for (SLTNode *n = scopeMetadata->scope.scopedFunctionsHead; n != NULL; n = sltGetNodeMetadata(n)->function.scopedFunctionNext) {
422 if (strcmp(n->functionDefinitionIdentifier->identifierStringValue, name) == 0) {
423 *typeOut = VMNodeMetadataIdentifierTypeFunction;
424 //printf("GOT F %s\n", name);
425 return n;
426 }
427 }
428
429 for (SLTNode *n = scopeMetadata->scope.scopedVariablesHead; n != NULL; n = sltGetNodeMetadata(n)->variable.scopedVariableNext) {
430 if (strcmp(n->variableDefinitionIdentifier->identifierStringValue, name) == 0) {
431 *typeOut = VMNodeMetadataIdentifierTypeVariable;
432 //printf("GOT V %s\n", name);
433 return n;
434 }
435 }
436
437 for (SLTNode *n = scopeMetadata->scope.scopedParametersHead; n != NULL; n = sltGetNodeMetadata(n)->parameter.scopedParameterNext) {
438 if (strcmp(n->functionParameterDefinitionIdentifier->identifierStringValue, name) == 0) {
439 *typeOut = VMNodeMetadataIdentifierTypeParameter;
440 //printf("GOT P %s\n", name);
441 return n;
442 }
443 }
444
445 if (scopeMetadata->scope.parentScope != NULL) {
446 node = scopeMetadata->scope.parentScope;
447 } else {
448 break;
449 }
450 }
451
452 return NULL;
453 }
454
455 static void resolveDefinitions(SLTNode *node, void *userParameter) {
456 VMGeneratorVisitor *visitor = (VMGeneratorVisitor *)userParameter;
457 VMNodeMetadata *metadata = sltGetNodeMetadata(node);
458
459 switch (node->type) {
460 case SLTNodeTypeIdentifier:
461 metadata->identifier.resolvedNode = resolveDefinition(&metadata->identifier.type, node, node->identifierStringValue);
462 //printf("trying to get %s %x\n", node->stringValue, metadata->identifier.resolvedNode);
463 //metadata->variable.scopedVariableNext = metadata->scope.scopedVariablesHead;
464 //metadata->scope.scopedVariablesHead = node;
465 break;
466
467 default:
468 break;
469 }
470 }
471
472 static void resolveDefinitionsNativeFunctions(SLTNode *node, void *userParameter) {
473 VMGeneratorVisitor *visitor = (VMGeneratorVisitor *)userParameter;
474 VMNodeMetadata *metadata = sltGetNodeMetadata(node);
475
476 switch (node->type) {
477 case SLTNodeTypeFunctionCall:
478 if (sltGetNodeMetadata(node->functionCallFunction)->identifier.resolvedNode == NULL) {
479 metadata->functionCall.instruction = node->functionCallFunction->identifierStringKeyValue;
480 metadata->functionCall.native = true;
481 }
482
483 default:
484 break;
485 }
486 }
487
488
489
490 static void indexDefinitions(SLTNode *node, void *userParameter) {
491 VMGeneratorVisitor *visitor = (VMGeneratorVisitor *)userParameter;
492 VMNodeMetadata *metadata = sltGetNodeMetadata(node);
493
494 // Functions put their return value at the 0th stack position, modules start at -1
495 size_t idx = 1;
496
497 size_t parameterCount = 0;
498 for (SLTNode *parameter = metadata->scope.scopedParametersHead; parameter != NULL; ++parameterCount, parameter = sltGetNodeMetadata(parameter)->parameter.scopedParameterNext);
499
500 SLTNode *parameter = metadata->scope.scopedParametersHead;
501 while (parameter != NULL) {
502 sltGetNodeMetadata(parameter)->stack.offset = node->type == SLTNodeTypeModule ? -idx : (parameterCount + 1) - idx; // Parameter positions are inverted...
503 ++idx;
504 parameter = sltGetNodeMetadata(parameter)->parameter.scopedParameterNext;
505 }
506
507 SLTNode *variable = metadata->scope.scopedVariablesHead;
508 while (variable != NULL) {
509 sltGetNodeMetadata(variable)->stack.offset = node->type == SLTNodeTypeModule ? -idx : idx;
510 ++idx;
511 variable = sltGetNodeMetadata(variable)->variable.scopedVariableNext;
512 }
513 }
514
515
516
517 /*static void resolveTypes(SLTNode *node, void *userParameter) {
518 VMGeneratorVisitor *visitor = (VMGeneratorVisitor *)userParameter;
519 VMNodeMetadata *metadata = sltGetNodeMetadata(node);
520
521 switch (node->type) {
522 case SLTNodeTypeUnknown:
523 case SLTNodeTypeSequence:
524 generator_assert_msg(false, "unexpected: %s", sltNodeToString(node));// fixme
525 break;
526
527 case SLTNodeTypeIdentifier:
528 // ...??
529
530 case SLTNodeTypeBoolean:
531 case SLTNodeTypeInteger:
532 case SLTNodeTypeFloat:
533 case SLTNodeTypeString:
534
535 case SLTNodeTypeCompound:
536
537 case SLTNodeTypeArgument:
538
539 case SLTNodeTypeArrayAccess:
540 case SLTNodeTypeTypeAccess:
541
542 case SLTNodeTypeFunctionCall:
543
544 case SLTNodeTypeUnaryOperation:
545 case SLTNodeTypeBinaryOperation:
546
547 case SLTNodeTypeOperator:
548
549 case SLTNodeTypeAssignment:
550
551 case SLTNodeTypeReturn:
552 case SLTNodeTypeSleep:
553
554 case SLTNodeTypeForIteration:
555 case SLTNodeTypeDoIteration:
556 case SLTNodeTypeWhileIteration:
557
558 case SLTNodeTypeSelection:
559
560 case SLTNodeTypeStatementBlock:
561
562 case SLTNodeTypeVariableDefinition:
563
564 case SLTNodeTypeTypeDefinition:
565 case SLTNodeTypeTypeMemberDefinition:
566
567 case SLTNodeTypeFunctionDefinition:
568 case SLTNodeTypeFunctionParameterDefinition:
569
570 case SLTNodeTypeModule:
571
572
573 }
574
575 visitor.typeChanged = false;
576
577
578
579
580
581
582 if (node->dataType == SLTDataTypeUnknown) {
583 visitor->typeUnresolved = true;
584 }
585 }*/
586
587 static bool nodeTypeIsLoop(SLTNodeType type) {
588 switch (type) {
589 case SLTNodeTypeForIteration:
590 case SLTNodeTypeDoIteration:
591 case SLTNodeTypeWhileIteration:
592 return true;
593
594 default:
595 return false;
596 }
597 }
598
599 static SLTNode *findLoopScope(SLTNode *node) {
600 for (;;) {
601 node = findScope(node);
602
603 if (nodeTypeIsLoop(node->type)) {
604 return node;
605 }
606
607 VMNodeMetadata *metadata = sltGetNodeMetadata(node);
608 node = metadata->scope.parentScope;
609
610 generator_assert_msg(node != NULL, "failed to scope loop"); // FIXME
611 }
612 }
613
614 static void scopeIterationBreaks(SLTNode *node, void *userParameter) {
615 VMGeneratorVisitor *visitor = (VMGeneratorVisitor *)userParameter;
616 VMNodeMetadata *metadata = sltGetNodeMetadata(node);
617
618 switch (node->type) {
619 case SLTNodeTypeBreak: {
620 VMNodeMetadata *scopeMetadata = sltGetNodeMetadata(findLoopScope(node));
621 metadata->breakStatement.scopedBreakNext = scopeMetadata->scope.scopedBreaksHead;
622 scopeMetadata->scope.scopedBreaksHead = node;
623 break;
624 }
625
626 default:
627 break;
628 }
629 }
630
631
632 static SVMPointer generateValueInstructions(VMGeneratorOutputScope *generator, SLTNode *node, SVMOperand target) {
633 VMNodeMetadata *metadata = sltGetNodeMetadata(node);
634
635 switch (node->type) {
636 case SLTNodeTypeIdentifier: {
637 SVMOperand source = { .stackOffset = generatorResolveIdentifier(generator, node) };
638 return generatorAddInstruction(generator, SVMOpcodeMOV, target, source);
639 }
640
641 case SLTNodeTypeBoolean: {
642 SVMOperand source = { .integerLiteral = node->booleanValue ? 1 : 0 };
643 return generatorAddInstruction(generator, SVMOpcodeSET, target, source);
644 }
645
646 case SLTNodeTypeInteger: {
647 SVMOperand source = { .integerLiteral = FIXED(node->integerValue) };
648 return generatorAddInstruction(generator, SVMOpcodeSET, target, source);
649 }
650
651 case SLTNodeTypeRawInteger: {
652 SVMOperand source = { .__raw = node->integerValue };
653 return generatorAddInstruction(generator, SVMOpcodeSET, target, source);
654 }
655
656 case SLTNodeTypeFloat: {
657 SVMOperand source = { .floatLiteral = FIXED_FROM_FLOAT(node->floatValue) };
658 return generatorAddInstruction(generator, SVMOpcodeSET, target, source);
659 }
660
661 case SLTNodeTypeString: {
662 SVMOperand source = { .pointerLiteral = metadata->string.address }; // FIXME, string pool needed
663 return generatorAddInstruction(generator, SVMOpcodeSET, target, source);
664 }
665
666 case SLTNodeTypeKey: {
667 SVMOperand source = { .pointerLiteral = node->keyValue };
668 return generatorAddInstruction(generator, SVMOpcodeSET, target, source);
669 }
670
671 default:
672 generator_assert_msg(false, "unexpected: %s", sltNodeToString(node));// fixme
673 return -1; // FIXME
674 }
675 }
676
677 static SVMPointer generateExpressionInstructions(VMGeneratorOutputScope *generator, SLTNode *node, SVMOperand target, SVMStackOffset workingStackOffset) {
678 VMNodeMetadata *metadata = sltGetNodeMetadata(node);
679
680 switch (node->type) {
681 case SLTNodeTypeBinaryOperation: {
682 SVMOperand lhsOperand = { .stackOffset = workingStackOffset };
683 generateExpressionInstructions(generator, node->binaryOperationLHS, lhsOperand, workingStackOffset + 1);
684
685 SVMOperand rhsOperand = { .stackOffset = workingStackOffset + 1 };
686 generateExpressionInstructions(generator, node->binaryOperationRHS, rhsOperand, workingStackOffset + 2);
687
688 switch (node->binaryOperationOperator->operatorType) {
689 case SLTOperatorTypeAdd:
690 return generatorAddInstruction(generator, SVMOpcodeADD, target, lhsOperand, rhsOperand);
691
692 case SLTOperatorTypeSubtract:
693 return generatorAddInstruction(generator, SVMOpcodeSUB, target, lhsOperand, rhsOperand);
694
695 case SLTOperatorTypeMultiply:
696 return generatorAddInstruction(generator, SVMOpcodeMUL, target, lhsOperand, rhsOperand);
697
698 case SLTOperatorTypeDivide:
699 return generatorAddInstruction(generator, SVMOpcodeDIV, target, lhsOperand, rhsOperand);
700
701 case SLTOperatorTypeModulo:
702 return generatorAddInstruction(generator, SVMOpcodeMOD, target, lhsOperand, rhsOperand);
703
704 case SLTOperatorTypeBitwiseAnd:
705 return generatorAddInstruction(generator, SVMOpcodeBAND, target, lhsOperand, rhsOperand);
706
707 case SLTOperatorTypeBitwiseOr:
708 return generatorAddInstruction(generator, SVMOpcodeBOR, target, lhsOperand, rhsOperand);
709
710 case SLTOperatorTypeBitwiseXor:
711 return generatorAddInstruction(generator, SVMOpcodeBXOR, target, lhsOperand, rhsOperand);
712
713 case SLTOperatorTypeLogicalAnd:
714 return generatorAddInstruction(generator, SVMOpcodeAND, target, lhsOperand, rhsOperand);
715
716 case SLTOperatorTypeLogicalOr:
717 return generatorAddInstruction(generator, SVMOpcodeOR, target, lhsOperand, rhsOperand);
718
719 case SLTOperatorTypeEqual:
720 return generatorAddInstruction(generator, SVMOpcodeEQ, target, lhsOperand, rhsOperand);
721
722 case SLTOperatorTypeNotEqual:
723 return generatorAddInstruction(generator, SVMOpcodeNEQ, target, lhsOperand, rhsOperand);
724
725 case SLTOperatorTypeLessThan:
726 return generatorAddInstruction(generator, SVMOpcodeLT, target, lhsOperand, rhsOperand);
727
728 case SLTOperatorTypeLessThanEqual:
729 return generatorAddInstruction(generator, SVMOpcodeLTEQ, target, lhsOperand, rhsOperand);
730
731 case SLTOperatorTypeGreaterThan:
732 return generatorAddInstruction(generator, SVMOpcodeGT, target, lhsOperand, rhsOperand);
733
734 case SLTOperatorTypeGreaterThanEqual:
735 return generatorAddInstruction(generator, SVMOpcodeGTEQ, target, lhsOperand, rhsOperand);
736
737 default:
738 generator_assert_msg(false, "invalid binary operator %s", sltOperatorTypeToString(node->binaryOperationOperator->operatorType));
739 return -1;
740 }
741 }
742
743 case SLTNodeTypeUnaryOperation: {
744 SVMOperand operand = { .stackOffset = target.stackOffset };
745 generateExpressionInstructions(generator, node->unaryOperationOperand, operand, workingStackOffset);
746
747 switch (node->unaryOperationOperator->operatorType) {
748 //case SLTOperatorTypePositive:
749 // return -1;
750
751 case SLTOperatorTypeNegative:
752 return generatorAddInstruction(generator, SVMOpcodeINV, target, operand);
753
754 case SLTOperatorTypeBitwiseNot:
755 return generatorAddInstruction(generator, SVMOpcodeBNOT, target, operand);
756
757 case SLTOperatorTypeLogicalNot:
758 return generatorAddInstruction(generator, SVMOpcodeNOT, target, operand);
759
760 default:
761 generator_assert_msg(false, "invalid unary operator %s", sltOperatorTypeToString(node->unaryOperationOperator->operatorType));
762 return -1;
763 }
764 }
765
766 case SLTNodeTypeArrayAccess:
767 generator_assert_msg(false, "not implemented: %s", sltNodeToString(node));
768 return -1;
769
770 case SLTNodeTypeFunctionCall: {
771 //generator_assert_msg(sltGetNodeMetadata(node->functionCallFunction)->identifier.resolvedNode != NULL, "unresolved function: %s", node->functionCallFunction->stringValue);// fixme
772
773 SVMPointer r = generatorNextInstruction(generator);
774
775 SVMInteger parameterCount = 0;
776 for (SLTNode *n = node->functionCallArguments; n != NULL; n = n->sequenceNext) {
777 ++parameterCount;
778 SVMStackOffset parameterTarget = workingStackOffset + parameterCount;
779 SVMOperand target = { .stackOffset = parameterTarget, };
780 generateExpressionInstructions(generator, n->sequenceNode->argumentExpression, target, parameterTarget);
781 }
782
783 // Offset the stack to make 0 where we're returning into...
784 SVMStackOffset stackOffset = workingStackOffset;// + parameterCount;
785 generatorAddInstruction(generator, SVMOpcodeSTK, stackOffset);
786
787 // Call the function
788 if (metadata->functionCall.native == false) {
789 metadata->functionCall.instruction = generatorAddInstruction(generator, SVMOpcodePUSHJUMP, 999); // Silly marker, we patch this later...
790 } else {
791 metadata->functionCall.instruction = generatorAddInstruction(generator, SVMOpcodeCALL, metadata->functionCall.instruction, parameterCount);
792 }
793
794 // Put the stack back
795 generatorAddInstruction(generator, SVMOpcodeSTK, -stackOffset);
796
797 // Move result
798 if (target.stackOffset != workingStackOffset) {
799 SVMOperand source = { .stackOffset = workingStackOffset };
800 generatorAddInstruction(generator, SVMOpcodeMOV, target, source);
801 }
802
803 return r;
804 }
805
806 case SLTNodeTypeTypeAccess:
807 generator_assert_msg(false, "not implemented: %s", sltNodeToString(node));
808 return -1;
809
810 case SLTNodeTypeCompound:
811 return generateExpressionInstructions(generator, node->compoundSubexpression, target, workingStackOffset);
812
813 default:
814 return generateValueInstructions(generator, node, target);
815 }
816 }
817
818 static SVMPointer generateStatementInstructions(VMGeneratorOutputScope *generator, SLTNode *node, SVMStackOffset workingStackOffset) {
819 switch (node->type) {
820 case SLTNodeTypeStatementBlock: {
821 SVMPointer r = generatorNextInstruction(generator);
822
823 // FIXME, call the function thing...
824 // FIXME, open some kind of scope??
825 for (SLTNode *n = node->statementBlockContents; n != NULL; n = n->sequenceNext) {
826 generateStatementInstructions(generator, n->sequenceNode, workingStackOffset);
827 }
828
829 return r;
830 }
831
832 case SLTNodeTypeVariableDefinition: {
833 SVMPointer r = generatorNextInstruction(generator);
834
835 if (node->variableDefinitionDefaultExpression != NULL) {
836 SVMOperand target = { .stackOffset = generatorResolveIdentifier(generator, node->variableDefinitionIdentifier), };
837 generateExpressionInstructions(generator, node->variableDefinitionDefaultExpression, target, workingStackOffset);
838 }
839
840 return r;
841 }
842
843 case SLTNodeTypeSelection: {
844 SVMPointer r = generatorNextInstruction(generator);
845
846 SVMOperand valid = { .stackOffset = 0, };
847 generateExpressionInstructions(generator, node->selectionValidExpression, valid, workingStackOffset + 1);
848 generatorAddInstruction(generator, SVMOpcodeNOT, valid, valid); // Inverse for this check...
849 SVMPointer patchPre = generatorAddInstruction(generator, SVMOpcodeJT, valid, 999);
850
851 if (node->selectionValidStatement != NULL) {
852 generateStatementInstructions(generator, node->selectionValidStatement, workingStackOffset);
853 }
854
855 if (node->selectionInvalidStatement != NULL) {
856 SVMPointer patchPost = generatorAddInstruction(generator, SVMOpcodeJUMP, 999);
857
858 SVMOperand target = { .pointerLiteral = generatorNextInstruction(generator), };
859 generatorPatchOperand(generator, patchPre, 1, target);
860
861 generateStatementInstructions(generator, node->selectionInvalidStatement, workingStackOffset);
862
863 target.pointerLiteral = generatorNextInstruction(generator);
864 generatorPatchOperand(generator, patchPost, 0, target);
865 } else {
866 SVMOperand target = { .pointerLiteral = generatorNextInstruction(generator), };
867 generatorPatchOperand(generator, patchPre, 1, target);
868 }
869
870 return r;
871 }
872
873 case SLTNodeTypeDoIteration:
874 case SLTNodeTypeForIteration:
875 case SLTNodeTypeWhileIteration: {
876 if (node->iterationInitialExpression != NULL) {
877 //SVMOperand target = { .stackOffset = 0, };
878 //generateExpressionInstructions(generator, node->iterationInitialExpression, target, workingStackOffset); // FIXME, is this a statement??
879 generateStatementInstructions(generator, node->iterationInitialExpression, workingStackOffset);
880 }
881
882 SVMPointer r = generatorNextInstruction(generator);
883
884 SVMPointer patchPre;
885 if (node->iterationPreValidExpression != NULL) {
886 SVMOperand valid = { .stackOffset = 0, };
887 generateExpressionInstructions(generator, node->iterationPreValidExpression, valid, workingStackOffset + 1);
888 generatorAddInstruction(generator, SVMOpcodeNOT, valid, valid); // Inverse for this check...
889 patchPre = generatorAddInstruction(generator, SVMOpcodeJT, valid, 999);
890 }
891
892 if (node->iterationStatement != NULL) {
893 generateStatementInstructions(generator, node->iterationStatement, workingStackOffset);
894 }
895
896 if (node->iterationLoopExpression != NULL) {
897 //SVMOperand target = { .stackOffset = 0, };
898 //generateExpressionInstructions(generator, node->iterationLoopExpression, target, workingStackOffset); // FIXME, is this a statement??
899 generateStatementInstructions(generator, node->iterationLoopExpression, workingStackOffset);
900 }
901
902 if (node->iterationPostValidExpression != NULL) {
903 SVMOperand valid = { .stackOffset = 0, };
904 generateExpressionInstructions(generator, node->iterationPostValidExpression, valid, workingStackOffset + 1);
905 generatorAddInstruction(generator, SVMOpcodeJT, valid, r);
906 } else {
907 generatorAddInstruction(generator, SVMOpcodeJUMP, r);
908 }
909
910 // Patch jump...
911 SVMOperand target = { .pointerLiteral = generatorNextInstruction(generator), };
912
913 if (node->iterationPreValidExpression != NULL) {
914 generatorPatchOperand(generator, patchPre, 1, target);
915 }
916
917 VMNodeMetadata *metadata = sltGetNodeMetadata(node);
918 for (SLTNode *v = metadata->scope.scopedBreaksHead; v != NULL; v = sltGetNodeMetadata(v)->breakStatement.scopedBreakNext) {
919 generatorPatchOperand(generator, sltGetNodeMetadata(v)->breakStatement.breakInstruction, 0, target);
920 }
921
922 return r;
923 }
924
925 case SLTNodeTypeAssignment: {
926 SVMOperand target = { .stackOffset = generatorResolveIdentifier(generator, node->assignmentTarget) };
927 return generateExpressionInstructions(generator, node->assignmentSource, target, workingStackOffset);
928 }
929
930 case SLTNodeTypeReturn: {
931 SVMPointer r = generatorNextInstruction(generator);
932
933 if (node->returnExpression != NULL) {
934 SVMOperand target = { .stackOffset = 0, }; // return is always at 0
935 generateExpressionInstructions(generator, node->returnExpression, target, workingStackOffset);
936 }
937 generatorAddInstruction(generator, SVMOpcodePOPJUMP);
938
939 return r;
940 }
941
942 case SLTNodeTypeSleep:
943 return generatorAddInstruction(generator, SVMOpcodeSLEEP);
944
945 case SLTNodeTypeBreak: {
946 VMNodeMetadata *metadata = sltGetNodeMetadata(node);
947 metadata->breakStatement.breakInstruction = generatorAddInstruction(generator, SVMOpcodeJUMP, 999);
948 return metadata->breakStatement.breakInstruction;
949 }
950
951 default: {
952 // generator_assert_msg(false, "not implemented as statement: %s", sltNodeToString(node));
953 SVMOperand target = { .stackOffset = 0, }; // FIXME!!!
954 return generateExpressionInstructions(generator, node, target, workingStackOffset);
955 }
956 }
957 }
958
959 static void generateFunctionDefinitionInstructions(VMGeneratorOutputScope *generator, SLTNode *node) {
960 VMNodeMetadata *metadata = sltGetNodeMetadata(node);
961
962 // count parameters, these are first on the stack...
963 size_t numParameters = 0;
964 for (SLTNode *p = metadata->scope.scopedParametersHead; p != NULL; ++numParameters, p = sltGetNodeMetadata(p)->parameter.scopedParameterNext);
965
966 // next, count the variables
967 size_t numVariables = 0;
968 for (SLTNode *v = metadata->scope.scopedVariablesHead; v != NULL; ++numVariables, v = sltGetNodeMetadata(v)->variable.scopedVariableNext);
969
970 metadata->function.address = generatorNextInstruction(generator);
971
972 SVMStackOffset workingStackOffset = 1 + numParameters + numVariables;
973 if (node->functionDefinitionBody != NULL) {
974 generator_assert(node->functionDefinitionBody->type == SLTNodeTypeSequence);
975 for (SLTNode *n = node->functionDefinitionBody; n != NULL; n = n->sequenceNext) {
976 generateStatementInstructions(generator, n->sequenceNode, workingStackOffset);
977 }
978 }
979
980 // fallback return
981 generatorAddInstruction(generator, SVMOpcodePOPJUMP);
982 }
983
984 static size_t generateModuleInstructions(VMGeneratorOutputScope *generator, SLTNode *node) {
985 generator_assert(node != NULL && node->type == SLTNodeTypeModule);
986
987 if (node->moduleStatementsAndDefinitions != NULL) {
988 SVMPointer start = generatorAddInstruction(generator, SVMOpcodeJUMP, 999);
989
990 generator_assert(node->moduleStatementsAndDefinitions->type == SLTNodeTypeSequence);
991
992 // do functions first...
993 for (SLTNode *n = node->moduleStatementsAndDefinitions; n != NULL; n = n->sequenceNext) {
994 if (n->sequenceNode->type == SLTNodeTypeFunctionDefinition) {
995 generateFunctionDefinitionInstructions(generator, n->sequenceNode);
996 }
997 }
998
999 // Patch to jump to the start...
1000 SVMOperand address = { .pointerLiteral = generatorNextInstruction(generator) };
1001 generatorPatchOperand(generator, start, 0, address);
1002
1003 // then do variables
1004 //for (SLTNode *n = node->moduleStatementsAndDefinitions; n != NULL; n = n->sequenceNext) {
1005 // switch (n->sequenceNode->type) {
1006 // case SLTNodeTypeFunctionDefinition:
1007 // Do nothing...
1008 // break;
1009
1010 //case SLTNodeTypeVariableDefinition:
1011 //generateStatementInstructions(generator, n->sequenceNode, 0);
1012 // break;
1013
1014 // default:
1015 //generator_assert_msg(false, "could not define %s", sltNodeTypeToString(n->sequenceNode->type));
1016 // break;
1017 // }
1018 //}
1019
1020 // statements
1021 for (SLTNode *n = node->moduleStatementsAndDefinitions; n != NULL; n = n->sequenceNext) {
1022 switch (n->sequenceNode->type) {
1023 //case SLTNodeTypeVariableDefinition:
1024 case SLTNodeTypeTypeDefinition:
1025 case SLTNodeTypeFunctionDefinition:
1026 // Do nothing...
1027 break;
1028
1029 default:
1030 generateStatementInstructions(generator, n->sequenceNode, 0);
1031 break;
1032 }
1033 }
1034 }
1035
1036 return 0;
1037 }
1038
1039
1040
1041
1042 static void patchFunctionCalls(SLTNode *node, void *userParameter) {
1043 VMGeneratorVisitor *visitor = (VMGeneratorVisitor *)userParameter;
1044 VMNodeMetadata *metadata = sltGetNodeMetadata(node);
1045
1046 if (node->type == SLTNodeTypeFunctionCall) {
1047 if (metadata->functionCall.native == false) {
1048 generator_assert_msg(sltGetNodeMetadata(node->functionCallFunction)->identifier.resolvedNode->type == SLTNodeTypeFunctionDefinition, "%s", sltNodeToString(sltGetNodeMetadata(node->functionCallFunction)->identifier.resolvedNode));
1049 SVMOperand operand = { .pointerLiteral = sltGetNodeMetadata(sltGetNodeMetadata(node->functionCallFunction)->identifier.resolvedNode)->function.address };
1050 generatorPatchOperand(visitor->generator, metadata->functionCall.instruction, 0, operand);
1051 }
1052 }
1053 }
1054
1055
1056
1057 SVMModule *slcGenerateVMInstructions(SLTNode *moduleNode) {
1058 VMGeneratorOutputScope *generator = generatorCreate();
1059
1060 VMGeneratorVisitor visitor;
1061
1062 sltTreeIterate(moduleNode, addNodeMetadata, NULL, NULL);
1063
1064 visitor.generator = generator;
1065 sltTreeIterate(moduleNode, findStrings, NULL, &visitor);
1066
1067 visitor.currentScope = NULL;
1068 sltTreeIterate(moduleNode, beginScopeNode, endScopeNode, &visitor);
1069
1070 visitor.generator = generator;
1071 sltTreeIterate(moduleNode, scopeDefinitions, NULL, &visitor);
1072 sltTreeIterate(moduleNode, resolveDefinitions, resolveDefinitionsNativeFunctions, &visitor);
1073 sltTreeIterate(moduleNode, indexDefinitions, NULL, &visitor);
1074
1075 sltTreeIterate(moduleNode, scopeIterationBreaks, NULL, &visitor);
1076
1077 /*do {
1078 visitor.typeUnresolved = false;
1079 visitor.typeChanged = false;
1080 sltTreeIterate(moduleNode, resolveTypes, NULL, &visitor);
1081 } while (visitor.typeUnresolved && visitor.typeChanged);*/
1082
1083 generateModuleInstructions(generator, moduleNode);
1084
1085 visitor.generator = generator;
1086 sltTreeIterate(moduleNode, patchFunctionCalls, NULL, &visitor);
1087
1088
1089 SVMModule *module = generatorFinalize(generator);
1090
1091
1092 /*for (size_t i = 0; i < generator->nextInstructionIdx; ++i) {
1093 SVMOpcode opcode = generator->instructions[i].instruction.opcode;
1094 switch (opcodeOperandCount(opcode)) {
1095 case 0:
1096 default:
1097 printf("%u : %s\n", i, svmOpcodeToString(opcode));
1098 break;
1099
1100 case 1:
1101 printf("%u : %s %d\n", i, svmOpcodeToString(opcode), generator->instructions[i].instruction.dst.stackOffset);
1102 break;
1103
1104 case 2:
1105 printf("%u : %s %d %d\n", i, svmOpcodeToString(opcode), generator->instructions[i].instruction.dst.stackOffset, generator->instructions[i].instruction.p1.stackOffset);
1106 break;
1107
1108 case 3:
1109 printf("%u : %s %d %d %d\n", i, svmOpcodeToString(opcode), generator->instructions[i].instruction.dst.stackOffset, generator->instructions[i].instruction.p1.stackOffset, generator->instructions[i].instruction.p2.stackOffset);
1110 break;
1111 }
1112 }*/
1113
1114 //fix references...
1115
1116 return module;
1117 }