| const OP = require('./op.js'); | |||||
| function TokenStream(input){ | function TokenStream(input){ | ||||
| var pos = 0; | var pos = 0; | ||||
| function peek(){ | function peek(){ | ||||
| return input[pos]; | |||||
| return (pos < input.length) ? input[pos] : null; | |||||
| } | } | ||||
| function next(){ | function next(){ | ||||
| let v = input[pos]; | |||||
| pos += 1; | |||||
| return v; | |||||
| if (pos < input.length){ | |||||
| let v = input[pos]; | |||||
| pos += 1; | |||||
| return v; | |||||
| } | |||||
| return null; | |||||
| } | } | ||||
| function line(){ | function line(){ | ||||
| die: die | die: die | ||||
| }; | }; | ||||
| } | } | ||||
| var stream = null; | |||||
| function isTokenType(type, val){ | |||||
| let t = stream.peek(); | |||||
| if (t !== null && t.type === type){ | |||||
| if (!val || t.val === val) | |||||
| return true; | |||||
| } | |||||
| return false; | |||||
| } | |||||
| var stream = null; | |||||
| function isPunc(ch){ | |||||
| return isTokenType("punk", ch); | |||||
| } | |||||
| function isOpCode(ch){ | |||||
| return isTokenType("opcode", ch); | |||||
| } | |||||
| 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 + "'."); | |||||
| } | |||||
| } | |||||
| function isLabel(ch){ | |||||
| return isTokenType("label", ch); | |||||
| } | |||||
| return { | |||||
| type: 'directive', | |||||
| args: args, | |||||
| line: d.line, | |||||
| col: d.col | |||||
| }; | |||||
| function isDirective(ch){ | |||||
| return isTokenType("directive", ch); | |||||
| } | } | ||||
| parseExpression(){ | |||||
| o = stream.peek(); | |||||
| if (o.type === 'directive'){ | |||||
| return parseDirective(); | |||||
| } | |||||
| function isOp(ch){ | |||||
| return isTokenType("op", ch); | |||||
| } | } | ||||
| parse(tokens){ | parse(tokens){ | ||||
| let p = { | let p = { | ||||
| type: "prog", | type: "prog", |