~pixelherodev/zyg

0205ad9e8cb840d3a1905618b799e27db41d42ea — Noam Preil 25 days ago d7fa82c
tmp
4 files changed, 44 insertions(+), 23 deletions(-)

M lexer.c
M parser.c
M sema.c
M test.bash -rwxr-xr-x => -rw-r--r--
M lexer.c => lexer.c +3 -0
@@ 115,6 115,9 @@ lex_alpha(void)
	if(ARG("while", 5)){
		ctx.index += 5;
		ctx.token.tag = C3_WHILE;
	}else if(ARG("extern", 6)){
		ctx.index += 6;
		ctx.token.tag = C3_EXTERN;
	}else if(ARG("export", 6)){
		ctx.index += 6;
		ctx.token.tag = C3_EXPORT;

M parser.c => parser.c +39 -22
@@ 45,7 45,7 @@ static struct {
static uint32_t p_assign_expr(void);
static uint32_t p_block(void);
static uint32_t p_expr(void);
static uint32_t p_fnexpr(int legacy);
static uint32_t p_fnexpr(int legacy, int external);
static uint32_t p_type_expr(void);
static uint32_t p_ident(void);
static uint32_t p_str(void);


@@ 83,8 83,8 @@ parser_cleanup(void)
		FATAL(__VA_ARGS__);

#define EXPECT(etag,...) \
	if(ctx.i >= ctx.accel.token_count || ctx.tokens.tags[ctx.i] != etag) \
		FATAL(__VA_ARGS__);
	if(ctx.i >= ctx.accel.token_count || ctx.tokens.tags[ctx.i] != etag){ \
		ERROR(__VA_ARGS__);abort();}

#define IS_CMP() (ctx.i< ctx.accel.token_count && ( \
	ctx.tokens.tags[ctx.i] == C3_DEQ || \


@@ 440,7 440,7 @@ p_primary_expr(void)
	if(parser_is(0, C3_RETURN))
		return p_return();
	if(parser_is(0, C3_FN))
		return p_fnexpr(0);
		return p_fnexpr(0, 0);
	if(parser_is(0, C3_LBRACE))
		return p_block();
	if(parser_is(0, C3_LBRACE))


@@ 719,11 719,13 @@ p_block(void)
struct prefix {
	enum{
		prefix_pointer,
		prefix_manypointer,
		prefix_array,
		prefix_slice,
		prefix_error,
		prefix_const,
	}tag;
	uint32_t value;
};

static struct prefix failed = { prefix_error };


@@ 750,17 752,23 @@ p_prefixtypeops(void)
		}
		if(parser_is(0, C3_LSQUARE)){
			parser_advance();
			if(!parser_is(0, C3_RSQUARE)){
				ERROR("TODO: arrays", 0);
				return &failed;
			}
			if(!stb_sb_ensure_capacity(&ops, 1, sizeof(struct prefix))){
				ERROR("ICE: OOM", 0);
				return &failed;
			}
			ops[stb_sb_count(ops)].tag = prefix_slice;
			if(parser_is(0, C3_ASTERISK) && parser_is(1, C3_RSQUARE)){
				ops[stb_sb_count(ops)].tag = prefix_slice;
				parser_advance();
				parser_advance();
			}
			else if(!parser_is(0, C3_RSQUARE)){
				ERROR("TODO: arrays %s", c3tagstr(ctx.tokens.tags[ctx.i]));
				return &failed;
			} else {
				ops[stb_sb_count(ops)].tag = prefix_slice;
				parser_advance();
			}
			stb_sb_increment(ops, 1);
			parser_advance();
			if(parser_is(0, C3_CONST)){
				if(!stb_sb_ensure_capacity(&ops, 1, sizeof(struct prefix))){
					ERROR("ICE: OOM", 0);


@@ 1156,10 1164,10 @@ p_fnproto(int legacy)
}

static uint32_t
p_fnexpr(int legacy)
p_fnexpr(int legacy, int external)
{
	uint32_t type;
	uint32_t block;
	uint32_t block = -1;
	uint32_t ident = -1;
	if(legacy){
		ident = p_ident();


@@ 1170,19 1178,25 @@ p_fnexpr(int legacy)
		ERROR("Failed to read fnproto", 0);
		return -1;
	}
	parser_advance();
	block = p_block();
	if(block == -1){
		ERROR("Failed to read block", 0);
		return -1;
	if(!external){
		parser_advance();
		block = p_block();
		if(block == -1){
			ERROR("Failed to read block", 0);
			return -1;
		}
	}
	return c3append(&ctx.tree, C3_VALUE_FN, 3, type, block, ident);
}

static uint32_t
p_fn_legacy(void)
p_fn_legacy(int external)
{
	uint32_t value = p_fnexpr(1);
	uint32_t value = p_fnexpr(1, external);
	if(external){
		parser_advance();
		EXPECT(C3_SCOLON, "Expected semicolon to end vardecl, found '%s'",c3tagstr(ctx.tokens.tags[ctx.i]));
	}
	return c3append(&ctx.tree, C3_CONST, 3, c3nodechild(ctx.tree, value, 2), c3nodechild(ctx.tree, value, 0), value);
}



@@ 1288,7 1302,7 @@ p_tl_decl(void)
		FATAL("TODO: thread locals", 0);
	}
	if(parser_is_consume(C3_FN))
		node = p_fn_legacy();
		node = p_fn_legacy(ext);
	else if(parser_is(0, C3_USINGNAMESPACE)){
		FATAL("TODO: usingnamespace",0);
	}


@@ 1330,10 1344,13 @@ p_container_field(void)
		parser_advance();
		type = p_type_expr();
		if(type == -1)
			FATAL("Failed to readi containerfield typeexpr", 0);
			FATAL("Failed to read containerfield typeexpr", 0);
	}
	if(parser_is(1, C3_EQ))
	else if(parser_is(1, C3_EQ)){
		FATAL("TODO: container field default",0);
	}
	else
		FATAL("container field requires type or initializer", 0);
	ret = c3append(&ctx.tree, C3_FIELD, 3, ident, type, value);
	if(ret == -1)
		OOM();

M sema.c => sema.c +2 -1
@@ 49,7 49,8 @@ anal_execute(c3ctx *c3)
			ERROR("Type analysis failed!", 0);
			return 0;
		}
		if(c3nodetag(*c3, t) == C3_VALUE_FN){
		// If function and has body (i.e. not external), generate IR
		if(c3nodetag(*c3, t) == C3_VALUE_FN && c3nodechild(*c3, t, 1) != -1){
			if(l_fn(t) == UINT32_MAX){
				ERROR("Failed to extract expression semantics", 0);
				return 0;

M test.bash => test.bash +0 -0