analyze looks for root export decl only in the root source file

This commit is contained in:
Andrew Kelley 2015-11-30 23:06:29 -07:00
parent cd68969115
commit 31cf43de54
3 changed files with 49 additions and 41 deletions

View file

@ -175,41 +175,46 @@ static void preview_function_declarations(CodeGen *g, ImportTableEntry *import,
} }
break; break;
case NodeTypeRootExportDecl: case NodeTypeRootExportDecl:
for (int i = 0; i < node->data.root_export_decl.directives->length; i += 1) { if (import == g->root_import) {
AstNode *directive_node = node->data.root_export_decl.directives->at(i); for (int i = 0; i < node->data.root_export_decl.directives->length; i += 1) {
Buf *name = &directive_node->data.directive.name; AstNode *directive_node = node->data.root_export_decl.directives->at(i);
Buf *param = &directive_node->data.directive.param; Buf *name = &directive_node->data.directive.name;
if (buf_eql_str(name, "version")) { Buf *param = &directive_node->data.directive.param;
set_root_export_version(g, param, directive_node); if (buf_eql_str(name, "version")) {
} else { set_root_export_version(g, param, directive_node);
add_node_error(g, directive_node, } else {
buf_sprintf("invalid directive: '%s'", buf_ptr(name))); add_node_error(g, directive_node,
buf_sprintf("invalid directive: '%s'", buf_ptr(name)));
}
} }
}
if (g->root_export_decl) { if (g->root_export_decl) {
add_node_error(g, node,
buf_sprintf("only one root export declaration allowed"));
} else {
g->root_export_decl = node;
if (!g->root_out_name)
g->root_out_name = &node->data.root_export_decl.name;
Buf *out_type = &node->data.root_export_decl.type;
OutType export_out_type;
if (buf_eql_str(out_type, "executable")) {
export_out_type = OutTypeExe;
} else if (buf_eql_str(out_type, "library")) {
export_out_type = OutTypeLib;
} else if (buf_eql_str(out_type, "object")) {
export_out_type = OutTypeObj;
} else {
add_node_error(g, node, add_node_error(g, node,
buf_sprintf("invalid export type: '%s'", buf_ptr(out_type))); buf_sprintf("only one root export declaration allowed"));
} else {
g->root_export_decl = node;
if (!g->root_out_name)
g->root_out_name = &node->data.root_export_decl.name;
Buf *out_type = &node->data.root_export_decl.type;
OutType export_out_type;
if (buf_eql_str(out_type, "executable")) {
export_out_type = OutTypeExe;
} else if (buf_eql_str(out_type, "library")) {
export_out_type = OutTypeLib;
} else if (buf_eql_str(out_type, "object")) {
export_out_type = OutTypeObj;
} else {
add_node_error(g, node,
buf_sprintf("invalid export type: '%s'", buf_ptr(out_type)));
}
if (g->out_type == OutTypeUnknown)
g->out_type = export_out_type;
} }
if (g->out_type == OutTypeUnknown) } else {
g->out_type = export_out_type; add_node_error(g, node,
buf_sprintf("root export declaration only valid in root source file"));
} }
break; break;
case NodeTypeUse: case NodeTypeUse:
@ -428,13 +433,6 @@ static void analyze_root(CodeGen *g, ImportTableEntry *import, AstNode *node) {
analyze_top_level_declaration(g, child); analyze_top_level_declaration(g, child);
} }
if (!g->root_out_name) {
add_node_error(g, node,
buf_sprintf("missing export declaration and output name not provided"));
} else if (g->out_type == OutTypeUnknown) {
add_node_error(g, node,
buf_sprintf("missing export declaration and export type not provided"));
}
} }
void semantic_analyze(CodeGen *g) { void semantic_analyze(CodeGen *g) {
@ -447,4 +445,12 @@ void semantic_analyze(CodeGen *g) {
ImportTableEntry *import = entry->value; ImportTableEntry *import = entry->value;
analyze_root(g, import, import->root); analyze_root(g, import, import->root);
} }
if (!g->root_out_name) {
add_node_error(g, g->root_import->root,
buf_sprintf("missing export declaration and output name not provided"));
} else if (g->out_type == OutTypeUnknown) {
add_node_error(g, g->root_import->root,
buf_sprintf("missing export declaration and export type not provided"));
}
} }

View file

@ -661,7 +661,7 @@ static void init(CodeGen *g, Buf *source_path) {
} }
static void codegen_add_code(CodeGen *g, Buf *source_path, Buf *source_code) { static ImportTableEntry *codegen_add_code(CodeGen *g, Buf *source_path, Buf *source_code) {
Buf full_path = BUF_INIT; Buf full_path = BUF_INIT;
os_path_join(g->root_source_dir, source_path, &full_path); os_path_join(g->root_source_dir, source_path, &full_path);
@ -715,13 +715,14 @@ static void codegen_add_code(CodeGen *g, Buf *source_path, Buf *source_code) {
codegen_add_code(g, &top_level_decl->data.use.path, &import_code); codegen_add_code(g, &top_level_decl->data.use.path, &import_code);
} }
} }
return import_entry;
} }
void codegen_add_root_code(CodeGen *g, Buf *source_path, Buf *source_code) { void codegen_add_root_code(CodeGen *g, Buf *source_path, Buf *source_code) {
init(g, source_path); init(g, source_path);
codegen_add_code(g, source_path, source_code); g->root_import = codegen_add_code(g, source_path, source_code);
if (g->verbose) { if (g->verbose) {
fprintf(stderr, "\nSemantic Analysis:\n"); fprintf(stderr, "\nSemantic Analysis:\n");

View file

@ -86,6 +86,7 @@ struct CodeGen {
int version_minor; int version_minor;
int version_patch; int version_patch;
bool verbose; bool verbose;
ImportTableEntry *root_import;
}; };
struct TypeNode { struct TypeNode {