Language now supports top level definitions. no more last-expression-is-a-value thing, it's also a def. Host knows to run the special os def
This commit is contained in:
parent
9b8916eb72
commit
31ef279f16
4 changed files with 36 additions and 8 deletions
|
|
@ -2,6 +2,7 @@ import type { Value } from './types';
|
||||||
|
|
||||||
// Literals and Variables
|
// Literals and Variables
|
||||||
|
|
||||||
|
|
||||||
export type Literal = {
|
export type Literal = {
|
||||||
kind: 'literal'
|
kind: 'literal'
|
||||||
value: Value
|
value: Value
|
||||||
|
|
|
||||||
14
src/main.ts
14
src/main.ts
|
|
@ -25,14 +25,20 @@ const cgCode = stdlibCode + '\n' +
|
||||||
try {
|
try {
|
||||||
const tokens = tokenize(cgCode);
|
const tokens = tokenize(cgCode);
|
||||||
const parser = new Parser(tokens, cgCode);
|
const parser = new Parser(tokens, cgCode);
|
||||||
const ast = parser.parse();
|
const definitions = parser.parse();
|
||||||
// console.log(ast);
|
// console.log(ast);
|
||||||
|
|
||||||
const env: Env = new Map(Object.entries(builtins));
|
const env: Env = new Map(Object.entries(builtins));
|
||||||
const appRecord = evaluate(ast, env, cgCode);
|
|
||||||
// console.log("appRecord", appRecord);
|
|
||||||
|
|
||||||
if (appRecord.kind !== 'record')
|
for (const def of definitions) {
|
||||||
|
const value = evaluate(def.body, env, cgCode);
|
||||||
|
env.set(def.name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
const appRecord = env.get('os');
|
||||||
|
console.log("appRecord", appRecord);
|
||||||
|
|
||||||
|
if (!appRecord || appRecord.kind !== 'record')
|
||||||
throw new Error('Expected record');
|
throw new Error('Expected record');
|
||||||
|
|
||||||
const init = appRecord.fields.init;
|
const init = appRecord.fields.init;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import type { Token } from './lexer'
|
import type { Token } from './lexer'
|
||||||
import type { AST, MatchCase, Pattern } from './ast'
|
import type { AST, MatchCase, Pattern, Definition } from './ast'
|
||||||
import { ParseError } from './error'
|
import { ParseError } from './error'
|
||||||
|
|
||||||
export class Parser {
|
export class Parser {
|
||||||
|
|
@ -114,8 +114,29 @@ export class Parser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
parse(): AST {
|
parse(): Definition[] {
|
||||||
return this.parseExpression();
|
const definitions: Definition[] = [];
|
||||||
|
|
||||||
|
while (this.current().kind !== 'eof') {
|
||||||
|
definitions.push(this.parseDefinition());
|
||||||
|
}
|
||||||
|
|
||||||
|
return definitions;
|
||||||
|
}
|
||||||
|
|
||||||
|
private parseDefinition(): Definition {
|
||||||
|
const nameToken = this.expect('ident');
|
||||||
|
const name = (nameToken as { value: string }).value;
|
||||||
|
|
||||||
|
this.expect('equals');
|
||||||
|
|
||||||
|
const body = this.parseExpression();
|
||||||
|
|
||||||
|
if (this.current().kind !== 'eof') {
|
||||||
|
this.expect('semicolon');
|
||||||
|
}
|
||||||
|
|
||||||
|
return { kind: 'definition', name, body, ...this.getPos(nameToken) };
|
||||||
}
|
}
|
||||||
|
|
||||||
private parseExpression(): AST {
|
private parseExpression(): AST {
|
||||||
|
|
|
||||||
|
|
@ -37,4 +37,4 @@ view = state viewport \
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
{ init = init, update = update, view = view }
|
os = { init = init, update = update, view = view }
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue