Gymbo

compiler.h
Go to the documentation of this file.
1
7 #pragma once
8 #include "parser.h"
9 #include "type.h"
10
11 namespace gymbo {
12
21 inline void gen_lval(Node *node, Prog &prg) {
22 if (node->kind != ND_LVAR) {
23 char em[] = "lvar is not a variable";
24 error(em);
25 }
26 prg.emplace_back(Instr(InstrType::Push, node->offset));
27 }
28
35 inline void gen(Node *node, Prog &prg) {
36 switch (node->kind) {
37 case (ND_RETURN): {
38 prg.emplace_back(Instr(InstrType::Done));
39 return;
40 }
41 case (ND_BLOCK): {
42 for (Node *b : node->blocks) {
43 gen(b, prg);
44 }
45 return;
46 }
47 case ND_IF: {
48 gen(node->cond, prg);
49 Prog then_prg, els_prg;
50 gen(node->then, then_prg);
51
52 if (node->els != nullptr) {
53 gen(node->els, els_prg);
54 } else {
55 els_prg.emplace_back(Instr(InstrType::Nop));
56 }
57 els_prg.emplace_back(Instr(InstrType::Push, 1 + then_prg.size()));
58 els_prg.emplace_back(Instr(InstrType::Jmp));
59
60 prg.emplace_back(Instr(InstrType::Push, 3 + els_prg.size()));
61 prg.emplace_back(Instr(InstrType::Swap));
62 prg.emplace_back(Instr(InstrType::JmpIf));
63 prg.insert(prg.end(), els_prg.begin(), els_prg.end());
64 prg.insert(prg.end(), then_prg.begin(), then_prg.end());
65 return;
66 }
67 case ND_NUM: {
68 prg.emplace_back(Instr(InstrType::Push, FloatToWord(node->val)));
69 return;
70 }
71 case ND_LVAR: {
72 gen_lval(node, prg);
73 prg.emplace_back(Instr(InstrType::Load));
74 return;
75 }
76 case ND_ASSIGN: {
77 gen_lval(node->lhs, prg);
78 prg.emplace_back(Instr(InstrType::Load));
79 gen(node->rhs, prg);
80 prg.emplace_back(Instr(InstrType::Swap));
81 prg.emplace_back(Instr(InstrType::Store));
82 return;
83 }
84 }
85
86 gen(node->lhs, prg);
87 gen(node->rhs, prg);
88
89 switch (node->kind) {
90 case ND_ADD:
91 prg.emplace_back(Instr(InstrType::Add));
92 return;
93 case ND_SUB:
94 prg.emplace_back(Instr(InstrType::Sub));
95 return;
96 case ND_MUL:
97 prg.emplace_back(Instr(InstrType::Mul));
98 return;
99 case ND_EQ:
100 prg.emplace_back(Instr(InstrType::Eq));
101 return;
102 case ND_NE:
103 prg.emplace_back(Instr(InstrType::Eq));
104 prg.emplace_back(Instr(InstrType::Not));
105 return;
106 case ND_LT:
107 prg.emplace_back(Instr(InstrType::Lt));
108 return;
109 case ND_LE:
110 prg.emplace_back(Instr(InstrType::Le));
111 return;
112 case ND_AND:
113 prg.emplace_back(Instr(InstrType::And));
114 return;
115 case ND_OR:
116 prg.emplace_back(Instr(InstrType::Or));
117 return;
118 }
119
120 char em[] = "Unsupported Node";
121 error(em);
122 }
123
133 inline void compile_ast(std::vector<Node *> code, Prog &prg) {
134 for (int i = 0; i < code.size(); i++) {
135 if (code[i] != nullptr) {
136 gen(code[i], prg);
137 } else {
138 prg.emplace_back(Instr(InstrType::Done));
139 }
140 }
141 }
142 } // namespace gymbo
gymbo::Instr
Class representing an instruction.
Definition: type.h:53
gymbo
Definition: compiler.h:11
gymbo::ND_BLOCK
@ ND_BLOCK
Definition: parser.h:131
gymbo::ND_MUL
@ ND_MUL
Definition: parser.h:116
gymbo::ND_NUM
@ ND_NUM
Definition: parser.h:127
gymbo::ND_SUB
@ ND_SUB
Definition: parser.h:115
gymbo::ND_ASSIGN
@ ND_ASSIGN
Definition: parser.h:125
gymbo::ND_LVAR
@ ND_LVAR
Definition: parser.h:126
gymbo::ND_RETURN
@ ND_RETURN
Definition: parser.h:128
gymbo::ND_EQ
@ ND_EQ
Definition: parser.h:121
gymbo::ND_NE
@ ND_NE
Definition: parser.h:122
gymbo::ND_ADD
@ ND_ADD
Definition: parser.h:114
gymbo::ND_LT
@ ND_LT
Definition: parser.h:123
gymbo::ND_OR
@ ND_OR
Definition: parser.h:119
gymbo::ND_LE
@ ND_LE
Definition: parser.h:124
gymbo::ND_IF
@ ND_IF
Definition: parser.h:129
gymbo::ND_AND
@ ND_AND
Definition: parser.h:118
gymbo::compile_ast
void compile_ast(std::vector< Node * > code, Prog &prg)
Compile the Abstract Syntax Tree (AST) into a sequence of instructions.
Definition: compiler.h:133
gymbo::InstrType::Eq
@ Eq
gymbo::InstrType::Or
@ Or
gymbo::InstrType::Lt
@ Lt
gymbo::InstrType::JmpIf
@ JmpIf
gymbo::InstrType::Mul
@ Mul
gymbo::InstrType::Jmp
@ Jmp
gymbo::InstrType::Swap
@ Swap
gymbo::InstrType::Push
@ Push
gymbo::InstrType::Not
@ Not
gymbo::InstrType::Nop
@ Nop
gymbo::InstrType::Le
@ Le
gymbo::InstrType::And
@ And
gymbo::InstrType::Sub
@ Sub
gymbo::InstrType::Add
@ Add
gymbo::InstrType::Load
@ Load
gymbo::InstrType::Done
@ Done
gymbo::InstrType::Store
@ Store
gymbo::gen_lval
void gen_lval(Node *node, Prog &prg)
Generates virtual instructions for a given AST node, representing the left-hand side of a variable as...
Definition: compiler.h:21
gymbo::FloatToWord
uint32_t FloatToWord(float val)
Converts a float value to a 32-bit word representation.
Definition: utils.h:36
gymbo::Prog
std::vector< Instr > Prog
Alias for a program, represented as a vector of instructions.
Definition: type.h:143
gymbo::gen
void gen(Node *node, Prog &prg)
Generates virtual instructions for a given AST node.
Definition: compiler.h:35
gymbo::error
void error(char *fmt,...)
Reports an error and exits the program.
Definition: tokenizer.h:44
parser.h
Implementation of parser.
gymbo::Node
Structure representing a node in the Abstract Syntax Tree (AST).
Definition: parser.h:137
gymbo::Node::lhs
Node * lhs
Left-hand side.
Definition: parser.h:139
gymbo::Node::blocks
std::vector< Node * > blocks
Vector of child blocks.
Definition: parser.h:144
gymbo::Node::offset
int offset
Offset.
Definition: parser.h:146
gymbo::Node::kind
NodeKind kind
Node kind.
Definition: parser.h:138
gymbo::Node::cond
Node * cond
Condition.
Definition: parser.h:141
gymbo::Node::val
float val
Used if kind is ND_NUM.
Definition: parser.h:145
gymbo::Node::rhs
Node * rhs
Right-hand side.
Definition: parser.h:140
gymbo::Node::els
Node * els
'Else' branch
Definition: parser.h:143
gymbo::Node::then
Node * then
'Then' branch
Definition: parser.h:142
type.h
Implementatations of basic alias, types, and classes.