shithub: mc

ref: da5bfc6d15a50130afdcd37ed9af737a81724506
dir: /mparse/parse.myr/

View raw version
use std

use "ast.use"
use "stab.use"
use "types.use"
use "tokdefs.use"
use "tok.use"
use "util.use"

pkg parse =
	const tsfile	: (ts : tokstream# -> file#)
;;

const tsfile = {ts
	var f

	f = std.mk([
		.uses = [][:],
		.libs = [][:],
		.extlibs = [][:],
		.dcls = [][:],
		.extinit = [][:],
		.init = `std.None,
		.globls = mkstab(),
		.builtin = mkstab(),
		.ns = std.mkht(std.strhash, std.streq),
	])
	f.globls.super = `std.Some f.builtin
	optendlns(ts)
	while true
		match tokpeek(ts)
		| (loc, `Teof):	
			break
		| (loc, `Tuse):
			usestmt(ts, f)
		| (loc, `Tpkg):
			pkgdef(ts, f)
		| (loc, `Ttrait):
			traitdef(ts, f)
		| (loc, `Ttype):
			tydef(ts, f)
		| (loc, tok):	
			if !decl(ts, ts)
				err(loc, "invalid top level item near {}", tok)
			;;
		;;
		endlns(ts)
	;;
	-> f
}

const usestmt = {ts, f
	match toknext(ts)
	| (loc, `Tuse): /* ok */
	| (loc, t):	err(loc, "unexpected token in use {}\n", t)
	;;

	match toknext(ts)
	| (loc, `Tstrlit str):	f.uses = std.slpush(f.uses, `Ulocal str)
	| (loc, `Tident id):	f.uses = std.slpush(f.uses, `Ulib id)
	| (loc, t):	err(loc, "unexpected {} after use\n", t)
	;;
}

const pkgdef = {ts, f
	match toknext(ts)
	| (loc, `Tpkg):	/* ok */
	| (loc, t):	err(loc, "unexpected token in pkg {}\n", t)
	;;

	match toknext(ts)
	| (loc, `Tident id):	setpkg(f, f.globls, id)
	| (loc, `Tgap):	/* pkg _ */
	| (loc, t):	err(loc, "invalid package name {}\n", t)
	;;

	match toknext(ts)
	| (loc, `Tasn):	/* ok */
	| (loc, t):	err(loc, "expected '=' after pkg name, got {}\n", t)
	;;

	pkgbody(ts, f)

	expectendblk(ts, f)
}

const pkgbody = {ts, f
	optendlns(ts)
}

const traitdef = {ts, f
}

const tydef = {ts, f
}

const decl = {ts, f
	-> false
}

const endlns = {ts
	match tokpeek(ts)
	| (loc, `Tendln):	optendlns(ts)
	| (loc, t):	err(loc, "expected \\n, got {}\n", t)
	;;
}

const optendlns = {ts
	while true
		match tokpeek(ts)
		| (loc, `Tendln):	toknext(ts)
		| _:	break
		;;
	;;
}

const expectendblk = {ts, f
	match toknext(ts)
	| (loc, `Tendblk):	/* ok */
	| (loc, t):	err(loc, "expected ;; after block, got {}\n", t)
	;;
}