~sircmpwn/ipcgen

9af9b9aa7cce8e9d1658cf1651d340ef8de8d112 — Drew DeVault 4 months ago 5022fe1
parse: implement cap lists
3 files changed, 52 insertions(+), 3 deletions(-)

M ast/ast.ha
M gen/client.ha
M parse/interface.ha
M ast/ast.ha => ast/ast.ha +2 -2
@@ 41,8 41,8 @@ export type method_kind = enum {
// A capability input or output.
export type capability = struct {
	name: str,
	// Empty string for none
	iface: str,
	// Empty for none
	iface: ident,
	variadic: bool,
};


M gen/client.ha => gen/client.ha +3 -0
@@ 64,6 64,9 @@ fn c_meth(
	iface: *ast::interface,
	meth: *ast::method,
) (void | io::error) = {
	assert(len(meth.caps_in) == 0);  // TODO
	assert(len(meth.caps_out) == 0); // TODO

	const id: ast::ident = [meth.name];
	const name = gen_name_upper(&id);
	defer free(name);

M parse/interface.ha => parse/interface.ha +47 -1
@@ 58,7 58,7 @@ fn method(lex: *lex::lexer) (ast::method | error) = {
	};

	if (try(lex, ltok::LBRACE)? is lex::token) {
		abort(); // TODO: Capability list
		capabilities(lex, &meth)?;
	};

	want(lex, ltok::LPAREN)?;


@@ 97,3 97,49 @@ fn method(lex: *lex::lexer) (ast::method | error) = {
	want(lex, ltok::SEMICOLON)?;
	return meth;
};

fn capabilities(lex: *lex::lexer, meth: *ast::method) (void | error) = {
	let caps = &meth.caps_in;
	for (true) {
		if (try(lex, ltok::RBRACE)? is lex::token) {
			break;
		};

		const name = strings::dup(want(lex, ltok::WORD)?.1 as str);
		let iface: ast::ident = [];
		if (try(lex, ltok::COLON)? is lex::token) {
			iface = ident(lex)?;
		};
		if (try(lex, ltok::ELLIPSIS) is lex::token) {
			abort(); // TODO: Variadic caps
		};

		append(caps, ast::capability {
			name = name,
			iface = iface,
			variadic = false,
		});

		const next = match (try(lex, ltok::COMMA, ltok::SEMICOLON)?) {
		case let tok: lex::token =>
			yield tok;
		case void =>
			want(lex, ltok::RBRACE)?;
			break;
		};

		switch (next.0) {
		case ltok::COMMA =>
			yield;
		case ltok::SEMICOLON =>
			if (caps == &meth.caps_in) {
				return mksyntaxerr(lex, [
					ltok::COMMA,
					ltok::RBRACE,
				], next);
			};
			caps = &meth.caps_out;
			yield;
		};
	};
};