Created
May 25, 2023 03:54
-
-
Save githiago-f/af465b8de27c99a8b2f26b2c70e3138b to your computer and use it in GitHub Desktop.
dummy programing language processor preview
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// memory registers | |
const vars = new Map(); // { varName: value } | |
// constants | |
const varStatement = /[^\s]\s?\=\s?[^\s]/i; | |
const conditionStatement = /[^\s]\s?(>=|<=|>|<|==)\s?[^\s]/; | |
const aritimeticStatement = /[0-9]*\s?(\*|\+|\/|\-|\%)\s?[0-9]*/; | |
const ifStatement = /^if\([^]+\):$/; | |
const whileStatement = /^while\([^]+\):$/; | |
const printStatement = /^print\([^]+\)/; | |
// interpreter functions | |
function interpreter(program) { | |
const lines = program.split(/\n/g); | |
for (let i = 0; i < lines.length; i++) { | |
const line = lines[i].trim(); | |
if(whileStatement.test(line)) { | |
const linesToJump = countNestedLines(lines[i], lines.slice(i+1)); | |
const nextLines = lines.slice(i+1, i + 1 + linesToJump); | |
handleLoops(line, nextLines, linesToJump); | |
i += linesToJump; | |
} | |
else if (ifStatement.test(line)) { | |
i += handleIf(lines[i], lines.slice(i + 1)); | |
} | |
else if (varStatement.test(line)) { | |
handleAssignment(line); | |
} | |
else if (printStatement.test(line)) { | |
console.log(atom(line.replace(/print\(|\)$/g, ''))); | |
} | |
} | |
} | |
function aritimatics(operation) { | |
let [left, op, right] = operation.split(/(\*|\+|\\|\-|\%)/); | |
left = left.trim(); | |
right = right.trim(); | |
switch (op) { | |
case '*': return atom(left) * atom(right); | |
case '/': return atom(left) / atom(right); | |
case '-': return atom(left) - atom(right); | |
case '%': return atom(left) % atom(right); | |
case '+': return atom(left) + atom(right); | |
} | |
} | |
function conditions(operation) { | |
let [left, operator, right] = operation.split(/(>=|<=|>|<|==)/); | |
left = left.trim(); | |
right = right.trim(); | |
switch (operator) { | |
case '>': return atom(left) > atom(right); | |
case '<': return atom(left) < atom(right); | |
case '>=': return atom(left) >= atom(right); | |
case '<=': return atom(left) <= atom(right); | |
case '==': return atom(left) === atom(right); | |
} | |
} | |
function atom(val) { | |
if (conditionStatement.test(val)) return conditions(val); | |
else if (aritimeticStatement.test(val)) return aritimatics(val); | |
else if (!isNaN(Number(val))) return Number(val); | |
else if (val === 'true') return true; | |
else if (val === 'false') return false; | |
else if (val.startsWith('"') && val.endsWith('"')) return val.replace(/"/g, ''); | |
else { | |
if (vars.has(val)) | |
return vars.get(val); | |
throw Error(val + ' is not defined'); | |
} | |
} | |
function handleAssignment(line) { | |
const [name, ...value] = line.split(/=/); | |
vars.set(name.trim(), atom(value.join('').trim())); | |
} | |
function countNestedLines(line, nextLines) { | |
function indentationCount(ln) { | |
if(!/^\s/.test(ln)) { | |
return 0; | |
} | |
return indentationCount(ln.slice(1)) + 1; | |
} | |
const spaces = indentationCount(line); | |
let nestedLines = 0; | |
for (const l of nextLines) { | |
const lineSpace = indentationCount(l); | |
if (lineSpace <= spaces) break; | |
nestedLines++; | |
} | |
return nestedLines; | |
} | |
function handleLoops(line, nextLines) { | |
const condition = () => atom(line.replace(/while\(|\)\:/g, '')); | |
while(condition()) { | |
interpreter(nextLines.join('\n')); | |
} | |
} | |
function handleIf(line, nextLines) { | |
const nestedLines = countNestedLines(line, nextLines); | |
const value = atom(line.trim().replace(/if\(|\)\:/g, '')); | |
if (value === true) return 0; | |
return nestedLines; | |
} | |
interpreter(` | |
two_pow_two = 2 * 2 | |
x = 1 | |
y = 2 | |
z = x >= y | |
string = "Teste??" | |
if(x == 1): | |
print("x is 1") | |
if(x >= y): | |
print("should not display") | |
while(x <= 5): | |
print(x) | |
if(x % 2 == 0): | |
print(x + " is even") | |
x = x + 1 | |
if(x > y): | |
print("HEHEHEH") | |
print("Test") | |
`); | |
console.table(vars); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment