Skip to content

Commit 744429c

Browse files
committed
Start of template runner
1 parent 7976cdb commit 744429c

2 files changed

Lines changed: 140 additions & 0 deletions

File tree

src/Runner.js

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
'use strict';
2+
3+
const RuntimeError = require('./error/Runtime');
4+
5+
const {
6+
OPERATOR_EQUALS,
7+
OPERATOR_NOT_EQUALS,
8+
OPERATOR_STRICT_EQUALS,
9+
OPERATOR_STRICT_NOT_EQUALS,
10+
OPERATOR_AND,
11+
OPERATOR_OR,
12+
OPERATOR_NOT,
13+
OPERATOR_GREATER_THAN,
14+
OPERATOR_LESS_THAN,
15+
OPERATOR_GREATER_EQUAL_THAN,
16+
OPERATOR_LESS_EQUAL_THAN,
17+
18+
PARSER_TYPE_ROOT,
19+
PARSER_TYPE_TEXT_LITERAL,
20+
PARSER_TYPE_INCLUDE,
21+
PARSER_TYPE_VALUE,
22+
PARSER_TYPE_VARIABLE,
23+
PARSER_TYPE_BRANCH,
24+
PARSER_TYPE_UNARY_OPERATOR,
25+
PARSER_TYPE_BINARY_OPERATOR
26+
} = require('./constants');
27+
28+
class Runner {
29+
constructor(ast, input) {
30+
this.ast = ast;
31+
this.input = input;
32+
this.result = [];
33+
}
34+
35+
invoke() {
36+
this.invokeRoot(this.ast);
37+
}
38+
39+
invokeRoot(ast) {
40+
for (const statement in ast.statements) {
41+
if (statement.type === PARSER_TYPE_TEXT_LITERAL) {
42+
this.result.push(statement.value);
43+
}
44+
else if (statement.type === PARSER_TYPE_INCLUDE) {
45+
this.invokeInclude(statement);
46+
}
47+
else (statement.type === PARSER_TYPE_BRANCH) {
48+
this.invokeBranch(statement);
49+
}
50+
}
51+
}
52+
53+
invokeInclude(statement) {
54+
const path = statement.value;
55+
56+
if (typeof path !== string) {
57+
throw new RuntimeError('Non string type passed to include.')
58+
}
59+
// TODO: include other file
60+
}
61+
62+
invokeBranch(statement) {
63+
for (const branch of statement.branches) {
64+
if (this.evaluateExpression(branch.condition)) {
65+
66+
}
67+
}
68+
}
69+
70+
evaluateExpression(expression) {
71+
if (expression.type === PARSER_TYPE_BINARY_OPERATOR) {
72+
return this.evaluateBinaryExpression(expression);
73+
}
74+
else if (expression.type === PARSER_TYPE_UNARY_OPERATOR) {
75+
return this.evaluateUnaryExpression(expression);
76+
}
77+
else if (expression.type === PARSER_TYPE_VALUE) {
78+
return expression.value;
79+
}
80+
else if (expression.type === PARSER_TYPE_VARIABLE) {
81+
return this.getValueFromVariable(expression.value);
82+
}
83+
}
84+
85+
evaluateBinaryExpression(expression) {
86+
if (expression.operator === OPERATOR_EQUALS) {
87+
return this.evaluateExpression(expression.left) == this.evaluateExpression(expression.right);
88+
}
89+
90+
if (expression.operator === OPERATOR_NOT_EQUALS) {
91+
return this.evaluateExpression(expression.left) != this.evaluateExpression(expression.right);
92+
}
93+
94+
if (expression.operator === OPERATOR_STRICT_EQUALS) {
95+
return this.evaluateExpression(expression.left) === this.evaluateExpression(expression.right);
96+
}
97+
98+
if (expression.operator === OPERATOR_STRICT_NOT_EQUALS) {
99+
return this.evaluateExpression(expression.left) !== this.evaluateExpression(expression.right);
100+
}
101+
102+
if (expression.operator === OPERATOR_AND) {
103+
return this.evaluateExpression(expression.left) && this.evaluateExpression(expression.right);
104+
}
105+
106+
if (expression.operator === OPERATOR_OR) {
107+
return this.evaluateExpression(expression.left) || this.evaluateExpression(expression.right);
108+
}
109+
110+
throw new RuntimeError(`Unknown operator: ${expression.operator}`);
111+
}
112+
113+
evaluateUnaryExpression(expression) {
114+
if (expression.operator === OPERATOR_NOT) {
115+
return !this.evaluateExpression(expression.expression);
116+
}
117+
118+
throw new RuntimeError(`Unknown operator: ${expression.operator}`);
119+
}
120+
121+
getValueFromVariable(name) {
122+
if (!name in this.input) {
123+
throw new RuntimeError(`Unset variable: ${name}`);
124+
}
125+
return this.input[name];
126+
}
127+
128+
}

src/error/Runtime.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
'use strict';
2+
3+
const GeneralError = require('./General');
4+
5+
class RuntimeError extends GeneralError {
6+
constructor(message, statement) {
7+
super(message);
8+
this.statement = statement;
9+
}
10+
}
11+
12+
module.exports = RuntimeError;

0 commit comments

Comments
 (0)