Exemple #1
0
void register_local_var(COMPILATION_CONTEXT *ctx, char *name) {
	SYMBOL_TABLE *s;
	HASH_FIND(hh, LOCALS, name, strlen(name), s);
	if(s) {
		return;
	}
	assert(N_LOCALS < MAX_LOCALS);
	s = NGS_MALLOC(sizeof(*s));
	s->name = ngs_strdup(name);
	s->index = N_LOCALS++;
	HASH_ADD_KEYPTR(hh, LOCALS, s->name, strlen(s->name), s);
	register_local_identifier(ctx, s->name);
}
Exemple #2
0
Fichier : ngs.c Projet : Wingie/ngs
int main(int argc, char **argv)
{
	ast_node *tree = NULL;
	VM vm;
	CTX ctx;
	char *bytecode;
	size_t len;
	IP ip;
	VALUE closure, result;
	int parse_ok;
	char *bootstrap_file_name;
	char *source_file_name;
	METHOD_RESULT mr;

	// Silence GCC -Wunused-function
	if(0) { yymatchDot(NULL); yyAccept(NULL, 0); }

	NGS_GC_INIT();
	// (causes warning) // NGS_GC_THR_INIT();

	yycontext yyctx;
	memset(&yyctx, 0, sizeof(yycontext));
	yyctx.fail_pos = -1;
	yyctx.fail_rule = "(unknown)";
	yyctx.lines = 0;
	yyctx.lines_postions[0] = 0;
	bootstrap_file_name = find_bootstrap_file();
	if(!bootstrap_file_name) {
		fprintf(stderr, "Cold not find bootstrap file\n");
		exit(100);
	}
	if(!strcmp(bootstrap_file_name, "-")) {
		source_file_name = ngs_strdup("<stdin>");
		yyctx.input_file = stdin;
	} else {
		source_file_name = bootstrap_file_name;
		yyctx.input_file = fopen(bootstrap_file_name, "r");
	}
	if(!yyctx.input_file) {
		fprintf(stderr, "Error while opening bootstrap file '%s': %d - %s\n", bootstrap_file_name, errno, strerror(errno));
		exit(101);
	}
	parse_ok = yyparse(&yyctx);
	// printf("parse_ok %d\n", parse_ok);
	if(!parse_ok) {
		fprintf(stderr, "NGS: Failed to parse at position %d (%s), rule %s. Exiting.\n", yyctx.fail_pos, sprintf_position(&yyctx, yyctx.fail_pos), yyctx.fail_rule);
		exit(2);
	}

	tree = yyctx.__;
	IF_DEBUG(COMPILER, print_ast(tree, 0);)
Exemple #3
0
SYMBOL_TABLE *get_symbol_table_entry(SYMBOL_TABLE **st, char *name, int create_if_not_exists, int *created) {
	SYMBOL_TABLE *s;
	*created = 0;
	HASH_FIND(hh, *st, name, strlen(name), s);
	// printf("SYMBOL TABLE QUERY %s (len %zu) %p\n", name, strlen(name), *st);
	if(s) {
		// printf("SYMBOL TABLE LOOKUP OK %s -> %p\n", name, s);
		return s;
	}
	if(!create_if_not_exists) {
		return NULL;
	}
	s = NGS_MALLOC(sizeof(*s));
	s->name = ngs_strdup(name);
	s->is_predefinded_global = 0;
	// HASH_ADD_STR(*st, name /* field */, s);
	HASH_ADD_KEYPTR(hh, *st, s->name, strlen(s->name), s);
	*created = 1;
	// printf("SYMBOL TABLE ADD OK %s -> %p\n", name, *st);
	return s;
}
Exemple #4
0
// TODO: maybe do it at parse time? That might be more complex but probably faster
// TODO: refactor for code deduplication
void register_local_vars(COMPILATION_CONTEXT *ctx, ast_node *node) {
	SYMBOL_TABLE *s;
	ast_node *ptr, *ptr2;
	switch(node->type) {
		case FUNC_NODE:
			if(node->first_child->next_sibling->next_sibling->next_sibling) {
				// Function has a name
				HASH_FIND(hh, IDENTIFIERS_SCOPES, node->first_child->next_sibling->next_sibling->next_sibling->name, strlen(node->first_child->next_sibling->next_sibling->next_sibling->name), s);
				if(!s) {
					register_local_var(ctx, node->first_child->next_sibling->next_sibling->next_sibling->name);
				}
			}
			return;
		case LOCAL_NODE:
			for(ptr=node->first_child; ptr; ptr=ptr->next_sibling) {
				switch(ptr->type) {
					case IDENTIFIER_NODE:
						register_local_var(ctx, ptr->name);
						break;
					case ASSIGNMENT_NODE:
						assert(ptr->first_child->type == IDENTIFIER_NODE);
						register_local_var(ctx, ptr->first_child->name);
						for(ptr2=ptr->first_child->next_sibling; ptr2; ptr2=ptr2->next_sibling) {
							register_local_vars(ctx, ptr2);
						}
						break;
					default:
						assert(0 == "Unexpected node type under LOCAL_NODE");
				}
			}
			break;
		case UPVAR_NODE:
			for(ptr=node->first_child; ptr; ptr=ptr->next_sibling) {
				switch(ptr->type) {
					case IDENTIFIER_NODE:
						{
							// TEMP
							IDENTIFIER_INFO identifier_info;
							identifier_info = resolve_identifier(ctx, ptr->name);
							assert(identifier_info.type == UPVAR_IDENTIFIER);
						}
						register_upvar_identifier(ctx, ptr->name);
						break;
					case ASSIGNMENT_NODE:
						assert(ptr->first_child->type == IDENTIFIER_NODE);
						{
							// TEMP
							IDENTIFIER_INFO identifier_info;
							identifier_info = resolve_identifier(ctx, ptr->first_child->name);
							assert(identifier_info.type == UPVAR_IDENTIFIER);
						}
						register_upvar_identifier(ctx, ptr->first_child->name);
						for(ptr2=ptr->first_child->next_sibling; ptr2; ptr2=ptr2->next_sibling) {
							register_local_vars(ctx, ptr2);
						}
						break;
					default:
						assert(0 == "Unexpected node type under UPVAR_NODE");
				}
			}
			break;
		case GLOBAL_NODE:
			for(ptr=node->first_child; ptr; ptr=ptr->next_sibling) {
				switch(ptr->type) {
					case IDENTIFIER_NODE:
						{
							// TEMP
							IDENTIFIER_INFO identifier_info;
							identifier_info = resolve_identifier(ctx, ptr->name);
							assert(identifier_info.type == GLOBAL_IDENTIFIER || identifier_info.type == NO_IDENTIFIER);
						}
						register_global_identifier(ctx, ptr->name);
						break;
					case ASSIGNMENT_NODE:
						assert(ptr->first_child->type == IDENTIFIER_NODE);
						{
							// TEMP
							IDENTIFIER_INFO identifier_info;
							identifier_info = resolve_identifier(ctx, ptr->first_child->name);
							assert(identifier_info.type == GLOBAL_IDENTIFIER || identifier_info.type == NO_IDENTIFIER);
						}
						register_global_identifier(ctx, ptr->first_child->name);
						for(ptr2=ptr->first_child->next_sibling; ptr2; ptr2=ptr2->next_sibling) {
							register_local_vars(ctx, ptr2);
						}
						break;
					default:
						assert(0 == "Unexpected node type under GLOBAL_NODE");
				}
			}
			break;
		case ASSIGNMENT_NODE:
			if(node->first_child->type == IDENTIFIER_NODE) {
				HASH_FIND(hh, IDENTIFIERS_SCOPES, node->first_child->name, strlen(node->first_child->name), s);
				if(!s) {
					IDENTIFIER_INFO identifier_info;
					identifier_info = resolve_identifier(ctx, node->first_child->name);
					if(identifier_info.type == UPVAR_IDENTIFIER) {
						s = NGS_MALLOC(sizeof(*s));
						s->name = ngs_strdup(node->first_child->name);
						s->is_predefinded_global = 0;
						s->index = UPVAR_IDENTIFIER;
						HASH_ADD_KEYPTR(hh, IDENTIFIERS_SCOPES, s->name, strlen(s->name), s);
					}
				}
				if(!s) {
					register_local_var(ctx, node->first_child->name);
				}
			}
			for(ptr=node->first_child->next_sibling; ptr; ptr=ptr->next_sibling) {
				register_local_vars(ctx, ptr);
			}
			break;
	}
	for(ptr=node->first_child; ptr; ptr=ptr->next_sibling) {
		register_local_vars(ctx, ptr);
	}
}