fix ident problem
This commit is contained in:
parent
78a29ce471
commit
e65f457530
3 changed files with 42 additions and 23 deletions
12
src/main.ts
Normal file
12
src/main.ts
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
import { parseProgram } from "./parser";
|
||||||
|
|
||||||
|
|
||||||
|
// Main
|
||||||
|
async function main() {
|
||||||
|
const filename = Bun.argv[2];
|
||||||
|
const contents = await Bun.file(filename).text()
|
||||||
|
|
||||||
|
const programAst = parseProgram(contents);
|
||||||
|
}
|
||||||
|
|
||||||
|
main();
|
|
@ -33,13 +33,22 @@ const alt = (...parsers) => (i: string) => {
|
||||||
return res;
|
return res;
|
||||||
};
|
};
|
||||||
|
|
||||||
const _: Parser = re(/\s*/) // whitespace
|
// whitespace
|
||||||
|
const __: Parser = re(/\s+/)
|
||||||
|
const _: Parser = re(/\s*/)
|
||||||
|
|
||||||
// Grammar
|
// Grammar
|
||||||
const ident: Parser = re(/(\_[A-Za-z0-9_]+)|([A-Za-z][A-Za-z0-9_]*)/);
|
const ident: Parser = re(/(\_[A-Za-z0-9_]+)|([A-Za-z][A-Za-z0-9_]*)/);
|
||||||
|
const kwd = (s: string) => (i: string) => {
|
||||||
|
const res = ident(i)
|
||||||
|
if (res.status === "err") return wrapErr(`expected ${s}`, res)
|
||||||
|
if (s !== res.value) return err(`expected ${s}`)
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
const ty: Parser = alt(
|
const ty: Parser = alt(
|
||||||
re(/uint/), re(/int/), re(/ptr/),
|
kwd("uint"), kwd("int"), kwd("ptr"),
|
||||||
re(/str/), ident,
|
kwd("str"), ident,
|
||||||
)
|
)
|
||||||
|
|
||||||
const exprL: Parser = alt(
|
const exprL: Parser = alt(
|
||||||
|
@ -54,17 +63,17 @@ const expr2: Parser = alt(
|
||||||
const expr1: Parser = alt(
|
const expr1: Parser = alt(
|
||||||
map(seq(expr2, _, re(/==/), _, expr2), ([left,,,,right]) => ({expr: "==", left, right})),
|
map(seq(expr2, _, re(/==/), _, expr2), ([left,,,,right]) => ({expr: "==", left, right})),
|
||||||
expr2)
|
expr2)
|
||||||
const expr: Parser = expr1
|
export const expr: Parser = expr1
|
||||||
|
|
||||||
const top: Parser = alt(
|
export const top: Parser = alt(
|
||||||
map(seq(re(/extern/), _, ident), (([, name]) => ({type: "extern", name}))),
|
map(seq(kwd("extern"), _, ident), (([, name]) => ({type: "extern", name}))),
|
||||||
seq(re(/struct/), _, ident, _, re(/:/)),
|
seq(kwd("struct"), _, ident, _, re(/:/)),
|
||||||
map(seq(re(/fn/), _, ident, _, re(/:/)), (([,, name]) => ({type: "func", name}))),
|
map(seq(kwd("fn"), _, ident, _, re(/:/)), (([,, name]) => ({type: "func", name}))),
|
||||||
)
|
)
|
||||||
const stmt: Parser = alt(
|
export const stmt: Parser = alt(
|
||||||
map(seq(re(/let/), _, ident, _, re(/=/), _, (i) => expr(i)),
|
map(seq(kwd("let"), _, ident, _, re(/=/), _, (i) => expr(i)),
|
||||||
([,, name,,,, value]) => ({stmt: "let",name, value})),
|
([,, name,,,, value]) => ({stmt: "let",name, value})),
|
||||||
map(seq(re(/if/), _, (i) => expr(i), _, re(/:/)), ([,, cond]) => ({stmt: "if", cond})),
|
map(seq(kwd("if"), _, (i) => expr(i), _, re(/:/)), ([,, cond]) => ({stmt: "if", cond})),
|
||||||
map((i) => expr(i), (expr) => ({stmt:"expr", expr})),
|
map((i) => expr(i), (expr) => ({stmt:"expr", expr})),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -75,7 +84,7 @@ interface Program {
|
||||||
functions: object[]
|
functions: object[]
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseProgram(input: string): Program {
|
export function parseProgram(input: string): Program {
|
||||||
let currentFunc: string | null = null;
|
let currentFunc: string | null = null;
|
||||||
let indentStack = [0];
|
let indentStack = [0];
|
||||||
let expectIndent = false;
|
let expectIndent = false;
|
||||||
|
@ -124,14 +133,4 @@ function parseProgram(input: string): Program {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Codegen
|
// Codegen
|
||||||
|
|
||||||
// Main
|
|
||||||
async function main() {
|
|
||||||
const filename = Bun.argv[2];
|
|
||||||
const contents = await Bun.file(filename).text()
|
|
||||||
|
|
||||||
const programAst = parseProgram(contents);
|
|
||||||
}
|
|
||||||
|
|
||||||
main();
|
|
8
test/parser.test.ts
Normal file
8
test/parser.test.ts
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
import {test,expect} from "bun:test"
|
||||||
|
import { stmt } from "../src/parser"
|
||||||
|
|
||||||
|
test("ifx", () => expect(stmt("ifx")).toMatchObject({status:"ok", value: {expr: {}}, remain: ""}))
|
||||||
|
test("ifx:", () => expect(stmt("ifx:")).toMatchObject({status:"ok", value: {expr: {}}, remain: ":"}))
|
||||||
|
test("if x:", () => expect(stmt("if x:")).toMatchObject({status:"ok", value: {stmt: "if"}, remain: ""}))
|
||||||
|
test("if(x):", () => expect(stmt("if(x):")).toMatchObject({status:"ok", value: {stmt: "if"}, remain: ""}))
|
||||||
|
test("let let = let", () => expect(stmt("let let = let")).toMatchObject({status:"ok", value: {stmt: "let"}, remain: ""}))
|
Loading…
Reference in a new issue