| function TokenStream(input){ | |||||
| var pos = 0; | |||||
| function peek(){ | |||||
| return input[pos]; | |||||
| } | |||||
| function next(){ | |||||
| let v = input[pos]; | |||||
| pos += 1; | |||||
| return v; | |||||
| } | |||||
| function line(){ | |||||
| return (pos < input.length) ? input[pos].line : -1; | |||||
| } | |||||
| function col(){ | |||||
| return (pos < input.length) ? input[pos].col : -1; | |||||
| } | |||||
| function eof(){ | |||||
| return (pos >= input.length); | |||||
| } | |||||
| function die(msg){ | |||||
| throw new Error(msg + " Line: " + input[pos].line + ", Col: " + input[pos].col); | |||||
| } | |||||
| return { | |||||
| peek: peek, | |||||
| next: next, | |||||
| line: line, | |||||
| col: col, | |||||
| eof, eof, | |||||
| die: die | |||||
| }; | |||||
| } | |||||
| var stream = null; | |||||
| parseDirective(){ | |||||
| let d = stream.next(); | |||||
| let args = []; | |||||
| while (stream.peek().line === d.line){ | |||||
| let a = stream.next(); | |||||
| switch(a.type){ | |||||
| case "number": | |||||
| // TODO: Check if math ops are called. | |||||
| case "string": | |||||
| args.push(a); | |||||
| break; | |||||
| case "label": | |||||
| args.push({ | |||||
| type: "var", | |||||
| val: a.val, | |||||
| line: a.line, | |||||
| col: a.col | |||||
| }); | |||||
| break; | |||||
| case "punc": | |||||
| // Ignore punctuations! | |||||
| break; | |||||
| default: | |||||
| stream.die("Invalid token '" + a.type + "'."); | |||||
| } | |||||
| } | |||||
| return { | |||||
| type: 'directive', | |||||
| args: args, | |||||
| line: d.line, | |||||
| col: d.col | |||||
| }; | |||||
| } | |||||
| parseExpression(){ | |||||
| o = stream.peek(); | |||||
| if (o.type === 'directive'){ | |||||
| return parseDirective(); | |||||
| } | |||||
| } | |||||
| parse(tokens){ | |||||
| let p = { | |||||
| type: "prog", | |||||
| expressions: []; | |||||
| }; | |||||
| stream = TokenStream(tokens); | |||||
| while (!stream.eof()){ | |||||
| p.expressions.push(parseExpression()); | |||||
| } | |||||
| stream = null; | |||||
| return p; | |||||
| } | |||||
| module.exports = Object.freeze({ | |||||
| parse: parse | |||||
| }); | |||||