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;
|
||||
};
|
||||
|
||||
const _: Parser = re(/\s*/) // whitespace
|
||||
// whitespace
|
||||
const __: Parser = re(/\s+/)
|
||||
const _: Parser = re(/\s*/)
|
||||
|
||||
// Grammar
|
||||
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(
|
||||
re(/uint/), re(/int/), re(/ptr/),
|
||||
re(/str/), ident,
|
||||
kwd("uint"), kwd("int"), kwd("ptr"),
|
||||
kwd("str"), ident,
|
||||
)
|
||||
|
||||
const exprL: Parser = alt(
|
||||
|
@ -54,17 +63,17 @@ const expr2: Parser = alt(
|
|||
const expr1: Parser = alt(
|
||||
map(seq(expr2, _, re(/==/), _, expr2), ([left,,,,right]) => ({expr: "==", left, right})),
|
||||
expr2)
|
||||
const expr: Parser = expr1
|
||||
export const expr: Parser = expr1
|
||||
|
||||
const top: Parser = alt(
|
||||
map(seq(re(/extern/), _, ident), (([, name]) => ({type: "extern", name}))),
|
||||
seq(re(/struct/), _, ident, _, re(/:/)),
|
||||
map(seq(re(/fn/), _, ident, _, re(/:/)), (([,, name]) => ({type: "func", name}))),
|
||||
export const top: Parser = alt(
|
||||
map(seq(kwd("extern"), _, ident), (([, name]) => ({type: "extern", name}))),
|
||||
seq(kwd("struct"), _, ident, _, re(/:/)),
|
||||
map(seq(kwd("fn"), _, ident, _, re(/:/)), (([,, name]) => ({type: "func", name}))),
|
||||
)
|
||||
const stmt: Parser = alt(
|
||||
map(seq(re(/let/), _, ident, _, re(/=/), _, (i) => expr(i)),
|
||||
export const stmt: Parser = alt(
|
||||
map(seq(kwd("let"), _, ident, _, re(/=/), _, (i) => expr(i)),
|
||||
([,, 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})),
|
||||
)
|
||||
|
||||
|
@ -75,7 +84,7 @@ interface Program {
|
|||
functions: object[]
|
||||
}
|
||||
|
||||
function parseProgram(input: string): Program {
|
||||
export function parseProgram(input: string): Program {
|
||||
let currentFunc: string | null = null;
|
||||
let indentStack = [0];
|
||||
let expectIndent = false;
|
||||
|
@ -125,13 +134,3 @@ function parseProgram(input: string): Program {
|
|||
}
|
||||
|
||||
// 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