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 = (y) => 5 + y in x(3)");
|
||||||
// const tokens2 = tokenize("let x = 5 in x * 4");
|
// const tokens2 = tokenize("let x = 5 in x * 4");
|
||||||
// const tokens2 = tokenize("(x, y) => x + y");
|
// 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 p2 = new Parser(tokens2);
|
||||||
const ast3 = p2.parse();
|
const ast3 = p2.parse();
|
||||||
console.log(ast3);
|
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 {
|
parse(): AST {
|
||||||
return this.parseExpression();
|
return this.parseExpression();
|
||||||
}
|
}
|
||||||
|
|
||||||
private parseExpression(): AST {
|
private parseExpression(): AST {
|
||||||
let left = this.parsePrimary();
|
return this.parseInfix();
|
||||||
|
}
|
||||||
|
|
||||||
|
private parseInfix(): AST {
|
||||||
|
let left = this.parseApplication();
|
||||||
|
|
||||||
while (this.isInfixOp()) {
|
while (this.isInfixOp()) {
|
||||||
const opToken = this.advance();
|
const opToken = this.advance();
|
||||||
const opName = this.tokenToOpName(opToken);
|
const opName = this.tokenToOpName(opToken);
|
||||||
const right = this.parsePrimary();
|
const right = this.parseApplication();
|
||||||
|
|
||||||
left = {
|
left = {
|
||||||
kind: 'apply',
|
kind: 'apply',
|
||||||
|
|
@ -74,6 +86,17 @@ export class Parser {
|
||||||
return left;
|
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 {
|
private parsePrimary(): AST {
|
||||||
const token = this.current();
|
const token = this.current();
|
||||||
|
|
||||||
|
|
@ -145,6 +168,11 @@ export class Parser {
|
||||||
return { kind: 'variable', name: token.value };
|
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}`);
|
throw new Error(`Unexpected token: ${token.kind}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue