parsing function application
This commit is contained in:
parent
1ed325e98b
commit
1fc116f2fe
2 changed files with 31 additions and 3 deletions
|
|
@ -24,7 +24,7 @@ console.log(tokenize(str));
|
|||
// const tokens2 = tokenize("let x = (y) => 5 + y in x(3)");
|
||||
// const tokens2 = tokenize("let x = 5 in x * 4");
|
||||
// const tokens2 = tokenize("(x, y) => x + y");
|
||||
const tokens2 = tokenize('[1, 2, 3]');
|
||||
const tokens2 = tokenize('map double [1, 2, 3]');
|
||||
const p2 = new Parser(tokens2);
|
||||
const ast3 = p2.parse();
|
||||
console.log(ast3);
|
||||
|
|
|
|||
|
|
@ -52,17 +52,29 @@ export class Parser {
|
|||
}
|
||||
}
|
||||
|
||||
private canStartPrimary(): boolean {
|
||||
const kind = this.current().kind;
|
||||
return kind === 'ident' || kind === 'type-ident' ||
|
||||
kind === 'int' || kind === 'float' || kind === 'string' ||
|
||||
kind === 'open-paren' || kind === 'open-bracket' ||
|
||||
kind === 'open-brace';
|
||||
}
|
||||
|
||||
parse(): AST {
|
||||
return this.parseExpression();
|
||||
}
|
||||
|
||||
private parseExpression(): AST {
|
||||
let left = this.parsePrimary();
|
||||
return this.parseInfix();
|
||||
}
|
||||
|
||||
private parseInfix(): AST {
|
||||
let left = this.parseApplication();
|
||||
|
||||
while (this.isInfixOp()) {
|
||||
const opToken = this.advance();
|
||||
const opName = this.tokenToOpName(opToken);
|
||||
const right = this.parsePrimary();
|
||||
const right = this.parseApplication();
|
||||
|
||||
left = {
|
||||
kind: 'apply',
|
||||
|
|
@ -74,6 +86,17 @@ export class Parser {
|
|||
return left;
|
||||
}
|
||||
|
||||
private parseApplication(): AST {
|
||||
let func = this.parsePrimary();
|
||||
|
||||
while (this.canStartPrimary()) {
|
||||
const arg = this.parsePrimary();
|
||||
func = { kind: 'apply', func, args: [arg] };
|
||||
}
|
||||
|
||||
return func;
|
||||
}
|
||||
|
||||
private parsePrimary(): AST {
|
||||
const token = this.current();
|
||||
|
||||
|
|
@ -145,6 +168,11 @@ export class Parser {
|
|||
return { kind: 'variable', name: token.value };
|
||||
}
|
||||
|
||||
if (token.kind === 'type-ident') {
|
||||
this.advance();
|
||||
return { kind: 'constructor', name: token.value };
|
||||
}
|
||||
|
||||
throw new Error(`Unexpected token: ${token.kind}`);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue