authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-01-26 16:00:39-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-01-26 16:00:39-07:00
loga73453a2680cdbe4decb946f5f8355e83b521aa2
tree93922996fba980dc65d648f9dfae7ddc50fe0419
parent5afe473a86c2fe32b6d7c472b71f88e70ac671c6

add c_import top level decl

see #88

6 files changed, 184 insertions(+), 38 deletions(-)

src/all_types.hpp+18-3
...@@ -136,7 +136,8 @@ enum NodeType {...@@ -136,7 +136,8 @@ enum NodeType {
136 NodeTypeArrayAccessExpr,136 NodeTypeArrayAccessExpr,
137 NodeTypeSliceExpr,137 NodeTypeSliceExpr,
138 NodeTypeFieldAccessExpr,138 NodeTypeFieldAccessExpr,
139 NodeTypeUse,139 NodeTypeImport,
140 NodeTypeCImport,
140 NodeTypeBoolLiteral,141 NodeTypeBoolLiteral,
141 NodeTypeNullLiteral,142 NodeTypeNullLiteral,
142 NodeTypeUndefinedLiteral,143 NodeTypeUndefinedLiteral,
...@@ -410,7 +411,7 @@ struct AstNodePrefixOpExpr {...@@ -410,7 +411,7 @@ struct AstNodePrefixOpExpr {
410 Expr resolved_expr;411 Expr resolved_expr;
411};412};
412413
413struct AstNodeUse {414struct AstNodeImport {
414 Buf path;415 Buf path;
415 ZigList<AstNode *> *directives;416 ZigList<AstNode *> *directives;
416 VisibMod visib_mod;417 VisibMod visib_mod;
...@@ -419,6 +420,15 @@ struct AstNodeUse {...@@ -419,6 +420,15 @@ struct AstNodeUse {
419 ImportTableEntry *import;420 ImportTableEntry *import;
420};421};
421422
423struct AstNodeCImport {
424 ZigList<AstNode *> *directives;
425 VisibMod visib_mod;
426 AstNode *block;
427
428 // populated by semantic analyzer
429 TopLevelDecl top_level_decl;
430};
431
422struct AstNodeIfBoolExpr {432struct AstNodeIfBoolExpr {
423 AstNode *condition;433 AstNode *condition;
424 AstNode *then_block;434 AstNode *then_block;
...@@ -699,7 +709,8 @@ struct AstNode {...@@ -699,7 +709,8 @@ struct AstNode {
699 AstNodeFnCallExpr fn_call_expr;709 AstNodeFnCallExpr fn_call_expr;
700 AstNodeArrayAccessExpr array_access_expr;710 AstNodeArrayAccessExpr array_access_expr;
701 AstNodeSliceExpr slice_expr;711 AstNodeSliceExpr slice_expr;
702 AstNodeUse use;712 AstNodeImport import;
713 AstNodeCImport c_import;
703 AstNodeIfBoolExpr if_bool_expr;714 AstNodeIfBoolExpr if_bool_expr;
704 AstNodeIfVarExpr if_var_expr;715 AstNodeIfVarExpr if_var_expr;
705 AstNodeWhileExpr while_expr;716 AstNodeWhileExpr while_expr;
...@@ -920,6 +931,9 @@ enum BuiltinFnId {...@@ -920,6 +931,9 @@ enum BuiltinFnId {
920 BuiltinFnIdAddWithOverflow,931 BuiltinFnIdAddWithOverflow,
921 BuiltinFnIdSubWithOverflow,932 BuiltinFnIdSubWithOverflow,
922 BuiltinFnIdMulWithOverflow,933 BuiltinFnIdMulWithOverflow,
934 BuiltinFnIdCInclude,
935 BuiltinFnIdCDefine,
936 BuiltinFnIdCUndef,
923};937};
924938
925struct BuiltinFnEntry {939struct BuiltinFnEntry {
...@@ -1051,6 +1065,7 @@ struct BlockContext {...@@ -1051,6 +1065,7 @@ struct BlockContext {
1051 ZigList<VariableTableEntry *> variable_list;1065 ZigList<VariableTableEntry *> variable_list;
1052 AstNode *parent_loop_node;1066 AstNode *parent_loop_node;
1053 LLVMZigDIScope *di_scope;1067 LLVMZigDIScope *di_scope;
1068 Buf *c_import_buf;
1054};1069};
10551070
1056#endif1071#endif
src/analyze.cpp+102-14
...@@ -21,6 +21,8 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B...@@ -21,6 +21,8 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B
21 AstNode *node);21 AstNode *node);
22static TypeTableEntry *analyze_error_literal_expr(CodeGen *g, ImportTableEntry *import,22static TypeTableEntry *analyze_error_literal_expr(CodeGen *g, ImportTableEntry *import,
23 BlockContext *context, AstNode *node, Buf *err_name);23 BlockContext *context, AstNode *node, Buf *err_name);
24static TypeTableEntry *analyze_block_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
25 TypeTableEntry *expected_type, AstNode *node);
2426
25static AstNode *first_executing_node(AstNode *node) {27static AstNode *first_executing_node(AstNode *node) {
26 switch (node->type) {28 switch (node->type) {
...@@ -54,7 +56,8 @@ static AstNode *first_executing_node(AstNode *node) {...@@ -54,7 +56,8 @@ static AstNode *first_executing_node(AstNode *node) {
54 case NodeTypeCharLiteral:56 case NodeTypeCharLiteral:
55 case NodeTypeSymbol:57 case NodeTypeSymbol:
56 case NodeTypePrefixOpExpr:58 case NodeTypePrefixOpExpr:
57 case NodeTypeUse:59 case NodeTypeImport:
60 case NodeTypeCImport:
58 case NodeTypeBoolLiteral:61 case NodeTypeBoolLiteral:
59 case NodeTypeNullLiteral:62 case NodeTypeNullLiteral:
60 case NodeTypeUndefinedLiteral:63 case NodeTypeUndefinedLiteral:
...@@ -1018,6 +1021,25 @@ static void resolve_error_value_decl(CodeGen *g, ImportTableEntry *import, AstNo...@@ -1018,6 +1021,25 @@ static void resolve_error_value_decl(CodeGen *g, ImportTableEntry *import, AstNo
1018 }1021 }
1019}1022}
10201023
1024static void resolve_c_import_decl(CodeGen *g, ImportTableEntry *import, AstNode *node) {
1025 assert(node->type == NodeTypeCImport);
1026
1027 AstNode *block_node = node->data.c_import.block;
1028
1029 BlockContext *child_context = new_block_context(node, import->block_context);
1030 child_context->c_import_buf = buf_alloc();
1031
1032 TypeTableEntry *resolved_type = analyze_block_expr(g, import, child_context,
1033 g->builtin_types.entry_void, block_node);
1034
1035 if (resolved_type->id == TypeTableEntryIdInvalid) {
1036 return;
1037 }
1038
1039 fprintf(stderr, "c import buf:\n%s\n", buf_ptr(child_context->c_import_buf));
1040 zig_panic("TODO");
1041}
1042
1021static void resolve_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode *node) {1043static void resolve_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode *node) {
1022 switch (node->type) {1044 switch (node->type) {
1023 case NodeTypeFnProto:1045 case NodeTypeFnProto:
...@@ -1053,9 +1075,12 @@ static void resolve_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode...@@ -1053,9 +1075,12 @@ static void resolve_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode
1053 case NodeTypeErrorValueDecl:1075 case NodeTypeErrorValueDecl:
1054 resolve_error_value_decl(g, import, node);1076 resolve_error_value_decl(g, import, node);
1055 break;1077 break;
1056 case NodeTypeUse:1078 case NodeTypeImport:
1057 // nothing to do here1079 // nothing to do here
1058 break;1080 break;
1081 case NodeTypeCImport:
1082 resolve_c_import_decl(g, import, node);
1083 break;
1059 case NodeTypeFnDef:1084 case NodeTypeFnDef:
1060 case NodeTypeDirective:1085 case NodeTypeDirective:
1061 case NodeTypeParamDecl:1086 case NodeTypeParamDecl:
...@@ -1501,6 +1526,7 @@ BlockContext *new_block_context(AstNode *node, BlockContext *parent) {...@@ -1501,6 +1526,7 @@ BlockContext *new_block_context(AstNode *node, BlockContext *parent) {
15011526
1502 if (parent) {1527 if (parent) {
1503 context->parent_loop_node = parent->parent_loop_node;1528 context->parent_loop_node = parent->parent_loop_node;
1529 context->c_import_buf = parent->c_import_buf;
1504 }1530 }
15051531
1506 if (node && node->type == NodeTypeFnDef) {1532 if (node && node->type == NodeTypeFnDef) {
...@@ -1997,7 +2023,7 @@ static TypeTableEntry *resolve_expr_const_val_as_float_num_lit(CodeGen *g, AstNo...@@ -1997,7 +2023,7 @@ static TypeTableEntry *resolve_expr_const_val_as_float_num_lit(CodeGen *g, AstNo
1997 }2023 }
1998}2024}
19992025
2000static TypeTableEntry *resolve_expr_const_val_as_bignum_op(CodeGen *g, AstNode *node, 2026static TypeTableEntry *resolve_expr_const_val_as_bignum_op(CodeGen *g, AstNode *node,
2001 bool (*bignum_fn)(BigNum *, BigNum *, BigNum *), AstNode *op1, AstNode *op2,2027 bool (*bignum_fn)(BigNum *, BigNum *, BigNum *), AstNode *op1, AstNode *op2,
2002 TypeTableEntry *resolved_type)2028 TypeTableEntry *resolved_type)
2003{2029{
...@@ -2521,7 +2547,7 @@ static VariableTableEntry *add_local_var(CodeGen *g, AstNode *source_node, Block...@@ -2521,7 +2547,7 @@ static VariableTableEntry *add_local_var(CodeGen *g, AstNode *source_node, Block
2521 if (name) {2547 if (name) {
2522 buf_init_from_buf(&variable_entry->name, name);2548 buf_init_from_buf(&variable_entry->name, name);
2523 VariableTableEntry *existing_var;2549 VariableTableEntry *existing_var;
2524 2550
2525 if (context->fn_entry) {2551 if (context->fn_entry) {
2526 existing_var = find_local_variable(context, name);2552 existing_var = find_local_variable(context, name);
2527 } else {2553 } else {
...@@ -3396,6 +3422,47 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry...@@ -3396,6 +3422,47 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry
3396 return resolve_expr_const_val_as_type(g, node, type_entry);3422 return resolve_expr_const_val_as_type(g, node, type_entry);
3397 }3423 }
3398 }3424 }
3425 case BuiltinFnIdCInclude:
3426 {
3427 if (!context->c_import_buf) {
3428 add_node_error(g, node, buf_sprintf("@c_include valid only in c_import blocks"));
3429 return g->builtin_types.entry_invalid;
3430 }
3431
3432 AstNode **str_node = node->data.fn_call_expr.params.at(0)->parent_field;
3433 TypeTableEntry *str_type = get_unknown_size_array_type(g, g->builtin_types.entry_u8, true);
3434 TypeTableEntry *resolved_type = analyze_expression(g, import, context, str_type, *str_node);
3435
3436 if (resolved_type->id == TypeTableEntryIdInvalid) {
3437 return resolved_type;
3438 }
3439
3440 ConstExprValue *const_str_val = &get_resolved_expr(*str_node)->const_val;
3441
3442 if (!const_str_val->ok) {
3443 add_node_error(g, *str_node, buf_sprintf("@c_include requires constant expression"));
3444 return g->builtin_types.entry_void;
3445 }
3446
3447 buf_appendf(context->c_import_buf, "#include \"");
3448 ConstExprValue *ptr_field = const_str_val->data.x_struct.fields[0];
3449 uint64_t len = ptr_field->data.x_ptr.len;
3450 for (uint64_t i = 0; i < len; i += 1) {
3451 ConstExprValue *char_val = ptr_field->data.x_ptr.ptr[i];
3452 uint64_t big_c = char_val->data.x_bignum.data.x_uint;
3453 assert(big_c <= UINT8_MAX);
3454 uint8_t c = big_c;
3455 buf_appendf(context->c_import_buf, "%c", c);
3456 }
3457 buf_appendf(context->c_import_buf, "\"\n");
3458
3459 return g->builtin_types.entry_void;
3460 }
3461 case BuiltinFnIdCDefine:
3462 zig_panic("TODO");
3463 case BuiltinFnIdCUndef:
3464 zig_panic("TODO");
3465
3399 }3466 }
3400 zig_unreachable();3467 zig_unreachable();
3401}3468}
...@@ -4038,7 +4105,8 @@ static TypeTableEntry *analyze_expression(CodeGen *g, ImportTableEntry *import,...@@ -4038,7 +4105,8 @@ static TypeTableEntry *analyze_expression(CodeGen *g, ImportTableEntry *import,
4038 case NodeTypeRoot:4105 case NodeTypeRoot:
4039 case NodeTypeRootExportDecl:4106 case NodeTypeRootExportDecl:
4040 case NodeTypeFnDef:4107 case NodeTypeFnDef:
4041 case NodeTypeUse:4108 case NodeTypeImport:
4109 case NodeTypeCImport:
4042 case NodeTypeLabel:4110 case NodeTypeLabel:
4043 case NodeTypeStructDecl:4111 case NodeTypeStructDecl:
4044 case NodeTypeStructField:4112 case NodeTypeStructField:
...@@ -4140,7 +4208,8 @@ static void analyze_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode...@@ -4140,7 +4208,8 @@ static void analyze_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode
4140 break;4208 break;
4141 }4209 }
4142 case NodeTypeRootExportDecl:4210 case NodeTypeRootExportDecl:
4143 case NodeTypeUse:4211 case NodeTypeImport:
4212 case NodeTypeCImport:
4144 case NodeTypeVariableDeclaration:4213 case NodeTypeVariableDeclaration:
4145 case NodeTypeErrorValueDecl:4214 case NodeTypeErrorValueDecl:
4146 case NodeTypeFnProto:4215 case NodeTypeFnProto:
...@@ -4340,7 +4409,8 @@ static void collect_expr_decl_deps(CodeGen *g, ImportTableEntry *import, AstNode...@@ -4340,7 +4409,8 @@ static void collect_expr_decl_deps(CodeGen *g, ImportTableEntry *import, AstNode
4340 case NodeTypeFnDecl:4409 case NodeTypeFnDecl:
4341 case NodeTypeParamDecl:4410 case NodeTypeParamDecl:
4342 case NodeTypeDirective:4411 case NodeTypeDirective:
4343 case NodeTypeUse:4412 case NodeTypeImport:
4413 case NodeTypeCImport:
4344 case NodeTypeLabel:4414 case NodeTypeLabel:
4345 case NodeTypeStructDecl:4415 case NodeTypeStructDecl:
4346 case NodeTypeStructField:4416 case NodeTypeStructField:
...@@ -4486,9 +4556,24 @@ static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, Ast...@@ -4486,9 +4556,24 @@ static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, Ast
4486 case NodeTypeRootExportDecl:4556 case NodeTypeRootExportDecl:
4487 resolve_top_level_decl(g, import, node);4557 resolve_top_level_decl(g, import, node);
4488 break;4558 break;
4489 case NodeTypeUse:4559 case NodeTypeImport:
4490 // already taken care of4560 // already taken care of
4491 break;4561 break;
4562 case NodeTypeCImport:
4563 {
4564 TopLevelDecl *decl_node = &node->data.c_import.top_level_decl;
4565 decl_node->deps.init(1);
4566 collect_expr_decl_deps(g, import, node->data.c_import.block, decl_node);
4567
4568 decl_node->name = buf_sprintf("c_import_%" PRIu32, node->create_index);
4569 decl_node->import = import;
4570 if (decl_node->deps.size() > 0) {
4571 g->unresolved_top_level_decls.put(decl_node->name, node);
4572 } else {
4573 resolve_top_level_decl(g, import, node);
4574 }
4575 break;
4576 }
4492 case NodeTypeErrorValueDecl:4577 case NodeTypeErrorValueDecl:
4493 // error value declarations do not depend on other top level decls4578 // error value declarations do not depend on other top level decls
4494 resolve_top_level_decl(g, import, node);4579 resolve_top_level_decl(g, import, node);
...@@ -4619,15 +4704,15 @@ void semantic_analyze(CodeGen *g) {...@@ -4619,15 +4704,15 @@ void semantic_analyze(CodeGen *g) {
46194704
4620 for (int i = 0; i < import->root->data.root.top_level_decls.length; i += 1) {4705 for (int i = 0; i < import->root->data.root.top_level_decls.length; i += 1) {
4621 AstNode *child = import->root->data.root.top_level_decls.at(i);4706 AstNode *child = import->root->data.root.top_level_decls.at(i);
4622 if (child->type == NodeTypeUse) {4707 if (child->type == NodeTypeImport) {
4623 for (int i = 0; i < child->data.use.directives->length; i += 1) {4708 for (int i = 0; i < child->data.import.directives->length; i += 1) {
4624 AstNode *directive_node = child->data.use.directives->at(i);4709 AstNode *directive_node = child->data.import.directives->at(i);
4625 Buf *name = &directive_node->data.directive.name;4710 Buf *name = &directive_node->data.directive.name;
4626 add_node_error(g, directive_node,4711 add_node_error(g, directive_node,
4627 buf_sprintf("invalid directive: '%s'", buf_ptr(name)));4712 buf_sprintf("invalid directive: '%s'", buf_ptr(name)));
4628 }4713 }
46294714
4630 ImportTableEntry *target_import = child->data.use.import;4715 ImportTableEntry *target_import = child->data.import.import;
4631 assert(target_import);4716 assert(target_import);
46324717
4633 target_import->importers.append({import, child});4718 target_import->importers.append({import, child});
...@@ -4760,7 +4845,8 @@ Expr *get_resolved_expr(AstNode *node) {...@@ -4760,7 +4845,8 @@ Expr *get_resolved_expr(AstNode *node) {
4760 case NodeTypeFnDecl:4845 case NodeTypeFnDecl:
4761 case NodeTypeParamDecl:4846 case NodeTypeParamDecl:
4762 case NodeTypeDirective:4847 case NodeTypeDirective:
4763 case NodeTypeUse:4848 case NodeTypeImport:
4849 case NodeTypeCImport:
4764 case NodeTypeStructDecl:4850 case NodeTypeStructDecl:
4765 case NodeTypeStructField:4851 case NodeTypeStructField:
4766 case NodeTypeStructValueField:4852 case NodeTypeStructValueField:
...@@ -4780,6 +4866,8 @@ TopLevelDecl *get_resolved_top_level_decl(AstNode *node) {...@@ -4780,6 +4866,8 @@ TopLevelDecl *get_resolved_top_level_decl(AstNode *node) {
4780 return &node->data.struct_decl.top_level_decl;4866 return &node->data.struct_decl.top_level_decl;
4781 case NodeTypeErrorValueDecl:4867 case NodeTypeErrorValueDecl:
4782 return &node->data.error_value_decl.top_level_decl;4868 return &node->data.error_value_decl.top_level_decl;
4869 case NodeTypeCImport:
4870 return &node->data.c_import.top_level_decl;
4783 case NodeTypeNumberLiteral:4871 case NodeTypeNumberLiteral:
4784 case NodeTypeReturnExpr:4872 case NodeTypeReturnExpr:
4785 case NodeTypeBinOpExpr:4873 case NodeTypeBinOpExpr:
...@@ -4808,7 +4896,7 @@ TopLevelDecl *get_resolved_top_level_decl(AstNode *node) {...@@ -4808,7 +4896,7 @@ TopLevelDecl *get_resolved_top_level_decl(AstNode *node) {
4808 case NodeTypeStringLiteral:4896 case NodeTypeStringLiteral:
4809 case NodeTypeCharLiteral:4897 case NodeTypeCharLiteral:
4810 case NodeTypeSymbol:4898 case NodeTypeSymbol:
4811 case NodeTypeUse:4899 case NodeTypeImport:
4812 case NodeTypeBoolLiteral:4900 case NodeTypeBoolLiteral:
4813 case NodeTypeNullLiteral:4901 case NodeTypeNullLiteral:
4814 case NodeTypeUndefinedLiteral:4902 case NodeTypeUndefinedLiteral:
src/codegen.cpp+13-6
...@@ -177,6 +177,9 @@ static LLVMValueRef gen_builtin_fn_call_expr(CodeGen *g, AstNode *node) {...@@ -177,6 +177,9 @@ static LLVMValueRef gen_builtin_fn_call_expr(CodeGen *g, AstNode *node) {
177 switch (builtin_fn->id) {177 switch (builtin_fn->id) {
178 case BuiltinFnIdInvalid:178 case BuiltinFnIdInvalid:
179 case BuiltinFnIdTypeof:179 case BuiltinFnIdTypeof:
180 case BuiltinFnIdCInclude:
181 case BuiltinFnIdCDefine:
182 case BuiltinFnIdCUndef:
180 zig_unreachable();183 zig_unreachable();
181 case BuiltinFnIdAddWithOverflow:184 case BuiltinFnIdAddWithOverflow:
182 case BuiltinFnIdSubWithOverflow:185 case BuiltinFnIdSubWithOverflow:
...@@ -2250,7 +2253,8 @@ static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) {...@@ -2250,7 +2253,8 @@ static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) {
2250 case NodeTypeFnDecl:2253 case NodeTypeFnDecl:
2251 case NodeTypeParamDecl:2254 case NodeTypeParamDecl:
2252 case NodeTypeDirective:2255 case NodeTypeDirective:
2253 case NodeTypeUse:2256 case NodeTypeImport:
2257 case NodeTypeCImport:
2254 case NodeTypeStructDecl:2258 case NodeTypeStructDecl:
2255 case NodeTypeStructField:2259 case NodeTypeStructField:
2256 case NodeTypeStructValueField:2260 case NodeTypeStructValueField:
...@@ -2930,6 +2934,9 @@ static void define_builtin_fns(CodeGen *g) {...@@ -2930,6 +2934,9 @@ static void define_builtin_fns(CodeGen *g) {
2930 create_builtin_fn_with_arg_count(g, BuiltinFnIdAddWithOverflow, "add_with_overflow", 4);2934 create_builtin_fn_with_arg_count(g, BuiltinFnIdAddWithOverflow, "add_with_overflow", 4);
2931 create_builtin_fn_with_arg_count(g, BuiltinFnIdSubWithOverflow, "sub_with_overflow", 4);2935 create_builtin_fn_with_arg_count(g, BuiltinFnIdSubWithOverflow, "sub_with_overflow", 4);
2932 create_builtin_fn_with_arg_count(g, BuiltinFnIdMulWithOverflow, "mul_with_overflow", 4);2936 create_builtin_fn_with_arg_count(g, BuiltinFnIdMulWithOverflow, "mul_with_overflow", 4);
2937 create_builtin_fn_with_arg_count(g, BuiltinFnIdCInclude, "c_include", 1);
2938 create_builtin_fn_with_arg_count(g, BuiltinFnIdCDefine, "c_define", 2);
2939 create_builtin_fn_with_arg_count(g, BuiltinFnIdCUndef, "c_undef", 1);
2933}2940}
29342941
29352942
...@@ -3138,8 +3145,8 @@ static ImportTableEntry *codegen_add_code(CodeGen *g, Buf *abs_full_path,...@@ -3138,8 +3145,8 @@ static ImportTableEntry *codegen_add_code(CodeGen *g, Buf *abs_full_path,
3138 }3145 }
3139 }3146 }
3140 }3147 }
3141 } else if (top_level_decl->type == NodeTypeUse) {3148 } else if (top_level_decl->type == NodeTypeImport) {
3142 Buf *import_target_path = &top_level_decl->data.use.path;3149 Buf *import_target_path = &top_level_decl->data.import.path;
3143 Buf full_path = BUF_INIT;3150 Buf full_path = BUF_INIT;
3144 Buf *import_code = buf_alloc();3151 Buf *import_code = buf_alloc();
3145 bool found_it = false;3152 bool found_it = false;
...@@ -3163,7 +3170,7 @@ static ImportTableEntry *codegen_add_code(CodeGen *g, Buf *abs_full_path,...@@ -3163,7 +3170,7 @@ static ImportTableEntry *codegen_add_code(CodeGen *g, Buf *abs_full_path,
3163 auto entry = g->import_table.maybe_get(abs_full_path);3170 auto entry = g->import_table.maybe_get(abs_full_path);
3164 if (entry) {3171 if (entry) {
3165 found_it = true;3172 found_it = true;
3166 top_level_decl->data.use.import = entry->value;3173 top_level_decl->data.import.import = entry->value;
3167 } else {3174 } else {
3168 if ((err = os_fetch_file_path(abs_full_path, import_code))) {3175 if ((err = os_fetch_file_path(abs_full_path, import_code))) {
3169 if (err == ErrorFileNotFound) {3176 if (err == ErrorFileNotFound) {
...@@ -3175,8 +3182,8 @@ static ImportTableEntry *codegen_add_code(CodeGen *g, Buf *abs_full_path,...@@ -3175,8 +3182,8 @@ static ImportTableEntry *codegen_add_code(CodeGen *g, Buf *abs_full_path,
3175 goto done_looking_at_imports;3182 goto done_looking_at_imports;
3176 }3183 }
3177 }3184 }
3178 top_level_decl->data.use.import = codegen_add_code(g,3185 top_level_decl->data.import.import = codegen_add_code(g,
3179 abs_full_path, search_path, &top_level_decl->data.use.path, import_code);3186 abs_full_path, search_path, &top_level_decl->data.import.path, import_code);
3180 found_it = true;3187 found_it = true;
3181 }3188 }
3182 break;3189 break;
src/parser.cpp+47-15
...@@ -123,8 +123,10 @@ const char *node_type_str(NodeType node_type) {...@@ -123,8 +123,10 @@ const char *node_type_str(NodeType node_type) {
123 return "Symbol";123 return "Symbol";
124 case NodeTypePrefixOpExpr:124 case NodeTypePrefixOpExpr:
125 return "PrefixOpExpr";125 return "PrefixOpExpr";
126 case NodeTypeUse:126 case NodeTypeImport:
127 return "Use";127 return "Import";
128 case NodeTypeCImport:
129 return "CImport";
128 case NodeTypeBoolLiteral:130 case NodeTypeBoolLiteral:
129 return "BoolLiteral";131 return "BoolLiteral";
130 case NodeTypeNullLiteral:132 case NodeTypeNullLiteral:
...@@ -329,8 +331,12 @@ void ast_print(AstNode *node, int indent) {...@@ -329,8 +331,12 @@ void ast_print(AstNode *node, int indent) {
329 case NodeTypeSymbol:331 case NodeTypeSymbol:
330 fprintf(stderr, "Symbol %s\n", buf_ptr(&node->data.symbol_expr.symbol));332 fprintf(stderr, "Symbol %s\n", buf_ptr(&node->data.symbol_expr.symbol));
331 break;333 break;
332 case NodeTypeUse:334 case NodeTypeImport:
333 fprintf(stderr, "%s '%s'\n", node_type_str(node->type), buf_ptr(&node->data.use.path));335 fprintf(stderr, "%s '%s'\n", node_type_str(node->type), buf_ptr(&node->data.import.path));
336 break;
337 case NodeTypeCImport:
338 fprintf(stderr, "%s\n", node_type_str(node->type));
339 ast_print(node->data.c_import.block, indent + 2);
334 break;340 break;
335 case NodeTypeBoolLiteral:341 case NodeTypeBoolLiteral:
336 fprintf(stderr, "%s '%s'\n", node_type_str(node->type),342 fprintf(stderr, "%s '%s'\n", node_type_str(node->type),
...@@ -2768,19 +2774,35 @@ static AstNode *ast_parse_import(ParseContext *pc, int *token_index,...@@ -2768,19 +2774,35 @@ static AstNode *ast_parse_import(ParseContext *pc, int *token_index,
2768 return nullptr;2774 return nullptr;
2769 *token_index += 1;2775 *token_index += 1;
27702776
2771 Token *use_name = &pc->tokens->at(*token_index);2777 Token *import_name = ast_eat_token(pc, token_index, TokenIdStringLiteral);
2772 *token_index += 1;
2773 ast_expect_token(pc, use_name, TokenIdStringLiteral);
27742778
2775 Token *semicolon = &pc->tokens->at(*token_index);2779 ast_eat_token(pc, token_index, TokenIdSemicolon);
2780
2781 AstNode *node = ast_create_node(pc, NodeTypeImport, import_kw);
2782 node->data.import.visib_mod = visib_mod;
2783 node->data.import.directives = directives;
2784
2785 parse_string_literal(pc, import_name, &node->data.import.path, nullptr, nullptr);
2786 normalize_parent_ptrs(node);
2787 return node;
2788}
2789
2790/*
2791CImportDecl : "c_import" Block
2792*/
2793static AstNode *ast_parse_c_import(ParseContext *pc, int *token_index,
2794 ZigList<AstNode*> *directives, VisibMod visib_mod)
2795{
2796 Token *c_import_kw = &pc->tokens->at(*token_index);
2797 if (c_import_kw->id != TokenIdKeywordCImport)
2798 return nullptr;
2776 *token_index += 1;2799 *token_index += 1;
2777 ast_expect_token(pc, semicolon, TokenIdSemicolon);
27782800
2779 AstNode *node = ast_create_node(pc, NodeTypeUse, import_kw);2801 AstNode *node = ast_create_node(pc, NodeTypeCImport, c_import_kw);
2780 node->data.use.visib_mod = visib_mod;2802 node->data.c_import.visib_mod = visib_mod;
2781 node->data.use.directives = directives;2803 node->data.c_import.directives = directives;
2804 node->data.c_import.block = ast_parse_block(pc, token_index, true);
27822805
2783 parse_string_literal(pc, use_name, &node->data.use.path, nullptr, nullptr);
2784 normalize_parent_ptrs(node);2806 normalize_parent_ptrs(node);
2785 return node;2807 return node;
2786}2808}
...@@ -2953,6 +2975,12 @@ static void ast_parse_top_level_decls(ParseContext *pc, int *token_index, ZigLis...@@ -2953,6 +2975,12 @@ static void ast_parse_top_level_decls(ParseContext *pc, int *token_index, ZigLis
2953 continue;2975 continue;
2954 }2976 }
29552977
2978 AstNode *c_import_node = ast_parse_c_import(pc, token_index, directives, visib_mod);
2979 if (c_import_node) {
2980 top_level_decls->append(c_import_node);
2981 continue;
2982 }
2983
2956 AstNode *struct_node = ast_parse_struct_decl(pc, token_index, directives, visib_mod);2984 AstNode *struct_node = ast_parse_struct_decl(pc, token_index, directives, visib_mod);
2957 if (struct_node) {2985 if (struct_node) {
2958 top_level_decls->append(struct_node);2986 top_level_decls->append(struct_node);
...@@ -3103,8 +3131,12 @@ void normalize_parent_ptrs(AstNode *node) {...@@ -3103,8 +3131,12 @@ void normalize_parent_ptrs(AstNode *node) {
3103 case NodeTypeFieldAccessExpr:3131 case NodeTypeFieldAccessExpr:
3104 set_field(&node->data.field_access_expr.struct_expr);3132 set_field(&node->data.field_access_expr.struct_expr);
3105 break;3133 break;
3106 case NodeTypeUse:3134 case NodeTypeImport:
3107 set_list_fields(node->data.use.directives);3135 set_list_fields(node->data.import.directives);
3136 break;
3137 case NodeTypeCImport:
3138 set_list_fields(node->data.c_import.directives);
3139 set_field(&node->data.c_import.block);
3108 break;3140 break;
3109 case NodeTypeBoolLiteral:3141 case NodeTypeBoolLiteral:
3110 // none3142 // none
src/tokenizer.cpp+3
...@@ -211,6 +211,8 @@ static void end_token(Tokenize *t) {...@@ -211,6 +211,8 @@ static void end_token(Tokenize *t) {
211 t->cur_tok->id = TokenIdKeywordPub;211 t->cur_tok->id = TokenIdKeywordPub;
212 } else if (mem_eql_str(token_mem, token_len, "export")) {212 } else if (mem_eql_str(token_mem, token_len, "export")) {
213 t->cur_tok->id = TokenIdKeywordExport;213 t->cur_tok->id = TokenIdKeywordExport;
214 } else if (mem_eql_str(token_mem, token_len, "c_import")) {
215 t->cur_tok->id = TokenIdKeywordCImport;
214 } else if (mem_eql_str(token_mem, token_len, "import")) {216 } else if (mem_eql_str(token_mem, token_len, "import")) {
215 t->cur_tok->id = TokenIdKeywordImport;217 t->cur_tok->id = TokenIdKeywordImport;
216 } else if (mem_eql_str(token_mem, token_len, "true")) {218 } else if (mem_eql_str(token_mem, token_len, "true")) {
...@@ -1041,6 +1043,7 @@ const char * token_name(TokenId id) {...@@ -1041,6 +1043,7 @@ const char * token_name(TokenId id) {
1041 case TokenIdKeywordPub: return "pub";1043 case TokenIdKeywordPub: return "pub";
1042 case TokenIdKeywordExport: return "export";1044 case TokenIdKeywordExport: return "export";
1043 case TokenIdKeywordImport: return "import";1045 case TokenIdKeywordImport: return "import";
1046 case TokenIdKeywordCImport: return "c_import";
1044 case TokenIdKeywordTrue: return "true";1047 case TokenIdKeywordTrue: return "true";
1045 case TokenIdKeywordFalse: return "false";1048 case TokenIdKeywordFalse: return "false";
1046 case TokenIdKeywordIf: return "if";1049 case TokenIdKeywordIf: return "if";
src/tokenizer.hpp+1
...@@ -21,6 +21,7 @@ enum TokenId {...@@ -21,6 +21,7 @@ enum TokenId {
21 TokenIdKeywordPub,21 TokenIdKeywordPub,
22 TokenIdKeywordExport,22 TokenIdKeywordExport,
23 TokenIdKeywordImport,23 TokenIdKeywordImport,
24 TokenIdKeywordCImport,
24 TokenIdKeywordTrue,25 TokenIdKeywordTrue,
25 TokenIdKeywordFalse,26 TokenIdKeywordFalse,
26 TokenIdKeywordIf,27 TokenIdKeywordIf,