| ... | @@ -175,41 +175,46 @@ static void preview_function_declarations(CodeGen *g, ImportTableEntry *import, | ... | @@ -175,41 +175,46 @@ static void preview_function_declarations(CodeGen *g, ImportTableEntry *import, |
| 175 | } | 175 | } |
| 176 | break; | 176 | break; |
| 177 | case NodeTypeRootExportDecl: | 177 | case NodeTypeRootExportDecl: |
| 178 | for (int i = 0; i < node->data.root_export_decl.directives->length; i += 1) { | 178 | if (import == g->root_import) { |
| 179 | AstNode *directive_node = node->data.root_export_decl.directives->at(i); | 179 | for (int i = 0; i < node->data.root_export_decl.directives->length; i += 1) { |
| 180 | Buf *name = &directive_node->data.directive.name; | 180 | AstNode *directive_node = node->data.root_export_decl.directives->at(i); |
| 181 | Buf *param = &directive_node->data.directive.param; | 181 | Buf *name = &directive_node->data.directive.name; |
| 182 | if (buf_eql_str(name, "version")) { | 182 | Buf *param = &directive_node->data.directive.param; |
| 183 | set_root_export_version(g, param, directive_node); | 183 | if (buf_eql_str(name, "version")) { |
| 184 | } else { | 184 | set_root_export_version(g, param, directive_node); |
| 185 | add_node_error(g, directive_node, | 185 | } else { |
| 186 | buf_sprintf("invalid directive: '%s'", buf_ptr(name))); | 186 | add_node_error(g, directive_node, |
| | 187 | buf_sprintf("invalid directive: '%s'", buf_ptr(name))); |
| | 188 | } |
| 187 | } | 189 | } |
| 188 | } | | |
| 189 | | 190 | |
| 190 | if (g->root_export_decl) { | 191 | if (g->root_export_decl) { |
| 191 | add_node_error(g, node, | | |
| 192 | buf_sprintf("only one root export declaration allowed")); | | |
| 193 | } else { | | |
| 194 | g->root_export_decl = node; | | |
| 195 | | | |
| 196 | if (!g->root_out_name) | | |
| 197 | g->root_out_name = &node->data.root_export_decl.name; | | |
| 198 | | | |
| 199 | Buf *out_type = &node->data.root_export_decl.type; | | |
| 200 | OutType export_out_type; | | |
| 201 | if (buf_eql_str(out_type, "executable")) { | | |
| 202 | export_out_type = OutTypeExe; | | |
| 203 | } else if (buf_eql_str(out_type, "library")) { | | |
| 204 | export_out_type = OutTypeLib; | | |
| 205 | } else if (buf_eql_str(out_type, "object")) { | | |
| 206 | export_out_type = OutTypeObj; | | |
| 207 | } else { | | |
| 208 | add_node_error(g, node, | 192 | add_node_error(g, node, |
| 209 | buf_sprintf("invalid export type: '%s'", buf_ptr(out_type))); | 193 | buf_sprintf("only one root export declaration allowed")); |
| | 194 | } else { |
| | 195 | g->root_export_decl = node; |
| | 196 | |
| | 197 | if (!g->root_out_name) |
| | 198 | g->root_out_name = &node->data.root_export_decl.name; |
| | 199 | |
| | 200 | Buf *out_type = &node->data.root_export_decl.type; |
| | 201 | OutType export_out_type; |
| | 202 | if (buf_eql_str(out_type, "executable")) { |
| | 203 | export_out_type = OutTypeExe; |
| | 204 | } else if (buf_eql_str(out_type, "library")) { |
| | 205 | export_out_type = OutTypeLib; |
| | 206 | } else if (buf_eql_str(out_type, "object")) { |
| | 207 | export_out_type = OutTypeObj; |
| | 208 | } else { |
| | 209 | add_node_error(g, node, |
| | 210 | buf_sprintf("invalid export type: '%s'", buf_ptr(out_type))); |
| | 211 | } |
| | 212 | if (g->out_type == OutTypeUnknown) |
| | 213 | g->out_type = export_out_type; |
| 210 | } | 214 | } |
| 211 | if (g->out_type == OutTypeUnknown) | 215 | } else { |
| 212 | g->out_type = export_out_type; | 216 | add_node_error(g, node, |
| | 217 | buf_sprintf("root export declaration only valid in root source file")); |
| 213 | } | 218 | } |
| 214 | break; | 219 | break; |
| 215 | case NodeTypeUse: | 220 | case NodeTypeUse: |
| ... | @@ -428,13 +433,6 @@ static void analyze_root(CodeGen *g, ImportTableEntry *import, AstNode *node) { | ... | @@ -428,13 +433,6 @@ static void analyze_root(CodeGen *g, ImportTableEntry *import, AstNode *node) { |
| 428 | analyze_top_level_declaration(g, child); | 433 | analyze_top_level_declaration(g, child); |
| 429 | } | 434 | } |
| 430 | | 435 | |
| 431 | if (!g->root_out_name) { | | |
| 432 | add_node_error(g, node, | | |
| 433 | buf_sprintf("missing export declaration and output name not provided")); | | |
| 434 | } else if (g->out_type == OutTypeUnknown) { | | |
| 435 | add_node_error(g, node, | | |
| 436 | buf_sprintf("missing export declaration and export type not provided")); | | |
| 437 | } | | |
| 438 | } | 436 | } |
| 439 | | 437 | |
| 440 | void semantic_analyze(CodeGen *g) { | 438 | void semantic_analyze(CodeGen *g) { |
| ... | @@ -447,4 +445,12 @@ void semantic_analyze(CodeGen *g) { | ... | @@ -447,4 +445,12 @@ void semantic_analyze(CodeGen *g) { |
| 447 | ImportTableEntry *import = entry->value; | 445 | ImportTableEntry *import = entry->value; |
| 448 | analyze_root(g, import, import->root); | 446 | analyze_root(g, import, import->root); |
| 449 | } | 447 | } |
| | 448 | |
| | 449 | if (!g->root_out_name) { |
| | 450 | add_node_error(g, g->root_import->root, |
| | 451 | buf_sprintf("missing export declaration and output name not provided")); |
| | 452 | } else if (g->out_type == OutTypeUnknown) { |
| | 453 | add_node_error(g, g->root_import->root, |
| | 454 | buf_sprintf("missing export declaration and export type not provided")); |
| | 455 | } |
| 450 | } | 456 | } |