-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathinterpreter.js
114 lines (114 loc) · 3.47 KB
/
interpreter.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
/*
YAPL: Yet Another Programming Language
Made for fun.
This is the statement interpreter.
*/
const colors = require("colors")
var ep = null
var cls = null
/**
*
* @param {String} statement The code to be run.
* @param {Env} env The environment to use.
*/
var nativeFuncs = { // functions that are native. All passed values are TSVar clones.
print(...data){
data.forEach((val, index)=>{
val = val.val
data[index] = val
})
console.log.apply(global, data)
},
reverse(str){
return new cls.TSVar(null, str.val.split("").reverse().join(""), ep.types.str)
}
}
//Converts a string to a TSVar. if an edit var(eVar) is passed, modifies it's value.
function strToNative(str, eVar) {
var output = null
var mc = null
if(mc = str.match(/^"((?:[^"\\]|\\.)+)"$/)){
str = mc[1]
output = new cls.TSVar(null, str, ep.types.str)
}else if(mc = str.match(/^([0-9]*)\.([0-9]+)$/)){
output = new cls.TSVar(null, parseFloat(mc[1]+"."+mc[2]))
}else if(mc = str.match(/^([0-9]+)$/)){
output = new cls.TSVar(null, parseInt(mc[1]), ep.types.int)
}else if(mc = str.match(/^(true|false|True|False)$/)){
output = new cls.TSVar(null, mc[1].toLowerCase() == "true", ep.types.bool)
}
if(!output){
throw new Error(`Could not parse value:${str}`)
}
if(eVar){
eVar.type = output.type
eVar.val = output.val
}
return output
}
function nativeToStr(tsvar){
var val = tsvar.val
var tp = typeof val
var output = null
if(tp === "string"){
output = `"${val}"`
}else if(tp === "number"){
output = `${val}`
}else if(tp === "boolean"){
output = (val ? "true" : "false")
}
return output
}
function parseType(str){
var type = ep.types.any
if(ep.types[str.toLowerCase()]){
type = ep.types[str.toLowerCase()]
}
return type
}
/**
*
* @param {String} statement The code to execute.
* @param {cls.Env} env The environment to run code in.
* @param {Object} lep Local version of EP constant.
* @returns {undefined} Nothing.
*/
module.exports = function interpretStatement(statement, env, lep){
cls = require("./classes")(lep)
ep = lep
statement = statement.trim()
if(statement == "")return
var envVars = env.list()
envVars.forEach((val, idx)=>{
var reg = new RegExp(env.contents[idx].name, "g")
statement = statement.replace(reg, val)
})
var mcs = { //Match Cases.
eqcheck: /(.*)\s*==\s*(.*)/,
func: /(.+)\s*\(\s*([^)]*)\s*\)$/,
var: /var\s+(\w+)\s+(.+)\s*=\s*(.+)/
}
var mc //What case we matched.
var stm = statement //Just an alias to make it less typing.
if(mc = stm.match(mcs.func)){
var funcName = mc[1]
var funcArgs = mc[2].split(',')
funcArgs.forEach((name, index)=>{
name = name.trim()
name = strToNative(name)
funcArgs[index] = name
})
if (nativeFuncs[funcName]) {
var output = nativeFuncs[funcName].apply(this, funcArgs);
if(typeof output !== "undefined"){
stm = stm.replace(nativeToStr(output))
}
}
} else if(mc = stm.match(mcs.var)){
env.add(mc[2], mc[3], parseType(mc[1]))
}
stm = stm.replace(mcs.eqcheck, (m, g1, g2)=>{
if(g1 == g2)return "true"
else return "false"
})
}