Remove use of `extern` keyword
bfa128abb665d66b2b9a5a7fc564a4d5fc643af59bd527799b6edbe1c7f9cb93
1 parent
04bdcb9f
lib/std/intrinsics.rad
+2 -2
| 3 | 3 | /// Environment call. |
|
| 4 | 4 | /// |
|
| 5 | 5 | /// Issues a system call with the given number and arguments. |
|
| 6 | 6 | /// Arguments and the return value are `i64` to support both 32-bit |
|
| 7 | 7 | /// emulator addresses and 64-bit native (AMD64) pointers. |
|
| 8 | - | @intrinsic pub extern fn ecall(number: u32, arg1: i64, arg2: i64, arg3: i64, arg4: i64) -> i64; |
|
| 8 | + | @intrinsic pub fn ecall(number: u32, arg1: i64, arg2: i64, arg3: i64, arg4: i64) -> i64; |
|
| 9 | 9 | ||
| 10 | 10 | /// Break out of program. |
|
| 11 | - | @intrinsic pub extern fn ebreak(); |
|
| 11 | + | @intrinsic pub fn ebreak(); |
lib/std/lang/parser.rad
+0 -4
| 878 | 878 | } |
|
| 879 | 879 | if consume(p, scanner::TokenKind::Pub) or consume(p, scanner::TokenKind::Export) { |
|
| 880 | 880 | let attrNode = nodeAttribute(p, ast::Attribute::Pub); |
|
| 881 | 881 | attrs.append(attrNode, p.allocator); |
|
| 882 | 882 | } |
|
| 883 | - | if consume(p, scanner::TokenKind::Extern) { |
|
| 884 | - | let attrNode = nodeAttribute(p, ast::Attribute::Extern); |
|
| 885 | - | attrs.append(attrNode, p.allocator); |
|
| 886 | - | } |
|
| 887 | 883 | if attrs.len > 0 { |
|
| 888 | 884 | return ast::Attributes { list: attrs }; |
|
| 889 | 885 | } |
|
| 890 | 886 | return nil; |
|
| 891 | 887 | } |
lib/std/lang/parser/tests.rad
+3 -13
| 1115 | 1115 | try testing::expect(super::check(&parser, scanner::TokenKind::Ident)); |
|
| 1116 | 1116 | } |
|
| 1117 | 1117 | ||
| 1118 | 1118 | /// Test parsing a function declaration with attributes. |
|
| 1119 | 1119 | @test fn testParseFnDeclAttributes() throws (testing::TestError) { |
|
| 1120 | - | let node = try! parseStmtStr("pub extern fn run();"); |
|
| 1120 | + | let node = try! parseStmtStr("pub fn run();"); |
|
| 1121 | 1121 | let case ast::NodeValue::FnDecl(decl) = node.value |
|
| 1122 | 1122 | else throw testing::TestError::Failed; |
|
| 1123 | 1123 | ||
| 1124 | 1124 | try expectIdent(decl.name, "run"); |
|
| 1125 | 1125 |
| 1139 | 1139 | try testing::expect(ast::attributesContains(&attrs, ast::Attribute::Pub)); |
|
| 1140 | 1140 | try testing::expect(ast::attributesContains(&attrs, ast::Attribute::Extern)); |
|
| 1141 | 1141 | try testing::expect(decl.body == nil); |
|
| 1142 | 1142 | } |
|
| 1143 | 1143 | ||
| 1144 | - | @test fn testParseFnDeclAttributesExplicitExternKeepsTwoAttrs() throws (testing::TestError) { |
|
| 1145 | - | let node = try! parseStmtStr("pub extern fn explicit();"); |
|
| 1146 | - | let case ast::NodeValue::FnDecl(decl) = node.value |
|
| 1147 | - | else throw testing::TestError::Failed; |
|
| 1148 | - | ||
| 1149 | - | let attrs = decl.attrs |
|
| 1150 | - | else throw testing::TestError::Failed; |
|
| 1151 | - | try testing::expect(attrs.list.len == 2); |
|
| 1152 | - | } |
|
| 1153 | - | ||
| 1154 | - | /// Test parsing a top-level function declaration with inferred extern. |
|
| 1144 | + | /// Test parsing a top-level function declaration with inferred extern from `;`. |
|
| 1155 | 1145 | @test fn testParseFnDeclInferredExtern() throws (testing::TestError) { |
|
| 1156 | 1146 | let node = try! parseStmtStr("fn run();"); |
|
| 1157 | 1147 | let case ast::NodeValue::FnDecl(decl) = node.value |
|
| 1158 | 1148 | else throw testing::TestError::Failed; |
|
| 1159 | 1149 |
| 1170 | 1160 | ||
| 1171 | 1161 | try testing::expect(ast::attributesContains(&attrs, ast::Attribute::Extern)); |
|
| 1172 | 1162 | try testing::expect(decl.body == nil); |
|
| 1173 | 1163 | } |
|
| 1174 | 1164 | ||
| 1175 | - | /// Test parsing a top-level exported function declaration with inferred extern. |
|
| 1165 | + | /// Test parsing a top-level exported function declaration with inferred extern from `;`. |
|
| 1176 | 1166 | @test fn testParseFnDeclExportInferredExtern() throws (testing::TestError) { |
|
| 1177 | 1167 | let node = try! parseStmtStr("export fn run();"); |
|
| 1178 | 1168 | let case ast::NodeValue::FnDecl(decl) = node.value |
|
| 1179 | 1169 | else throw testing::TestError::Failed; |
|
| 1180 | 1170 |
lib/std/lang/resolver.rad
+5 -5
| 498 | 498 | FnMissingReturn, |
|
| 499 | 499 | /// Function is missing a body. |
|
| 500 | 500 | FnMissingBody, |
|
| 501 | 501 | /// Function body is not expected. |
|
| 502 | 502 | FnUnexpectedBody, |
|
| 503 | - | /// Intrinsic function must be declared extern. |
|
| 504 | - | IntrinsicRequiresExtern, |
|
| 503 | + | /// Intrinsic function must not have a body. |
|
| 504 | + | IntrinsicUnexpectedBody, |
|
| 505 | 505 | /// Encountered loop control outside of a loop construct. |
|
| 506 | 506 | InvalidLoopControl, |
|
| 507 | 507 | /// `try` used when the enclosing function does not declare throws. |
|
| 508 | 508 | TryRequiresThrows, |
|
| 509 | 509 | /// `try` used to propagate an error not declared by the enclosing function. |
| 3082 | 3082 | }; |
|
| 3083 | 3083 | let retTy = *fnType.returnType; |
|
| 3084 | 3084 | let isExtern = ast::hasAttribute(sym.attrs, ast::Attribute::Extern); |
|
| 3085 | 3085 | let isIntrinsic = ast::hasAttribute(sym.attrs, ast::Attribute::Intrinsic); |
|
| 3086 | 3086 | ||
| 3087 | - | if isIntrinsic and not isExtern { |
|
| 3088 | - | throw emitError(self, node, ErrorKind::IntrinsicRequiresExtern); |
|
| 3089 | - | } |
|
| 3090 | 3087 | if let body = decl.body { |
|
| 3088 | + | if isIntrinsic { |
|
| 3089 | + | throw emitError(self, node, ErrorKind::IntrinsicUnexpectedBody); |
|
| 3090 | + | } |
|
| 3091 | 3091 | if isExtern { |
|
| 3092 | 3092 | throw emitError(self, node, ErrorKind::FnUnexpectedBody); |
|
| 3093 | 3093 | } |
|
| 3094 | 3094 | enterFn(self, node, fnType); // Enter function scope for body analysis. |
|
| 3095 | 3095 |
lib/std/lang/resolver/printer.rad
+2 -2
| 407 | 407 | io::print("function is missing a body"); |
|
| 408 | 408 | } |
|
| 409 | 409 | case super::ErrorKind::FnUnexpectedBody => { |
|
| 410 | 410 | io::print("function body is not expected"); |
|
| 411 | 411 | } |
|
| 412 | - | case super::ErrorKind::IntrinsicRequiresExtern => { |
|
| 413 | - | io::print("intrinsic function must be declared extern"); |
|
| 412 | + | case super::ErrorKind::IntrinsicUnexpectedBody => { |
|
| 413 | + | io::print("intrinsic function must not have a body"); |
|
| 414 | 414 | } |
|
| 415 | 415 | case super::ErrorKind::InvalidLoopControl => { |
|
| 416 | 416 | io::print("loop control outside of a loop construct"); |
|
| 417 | 417 | } |
|
| 418 | 418 | case super::ErrorKind::TryRequiresThrows => { |
lib/std/lang/scanner.rad
+2 -3
| 95 | 95 | ||
| 96 | 96 | // Module-related tokens. |
|
| 97 | 97 | Mod, Use, Super, |
|
| 98 | 98 | ||
| 99 | 99 | // Type or function attributes. |
|
| 100 | - | Pub, Export, Extern, Static, |
|
| 100 | + | Pub, Export, Static, |
|
| 101 | 101 | ||
| 102 | 102 | // Trait-related tokens. |
|
| 103 | 103 | Trait, Instance, |
|
| 104 | 104 | ||
| 105 | 105 | // Type-related tokens. |
| 114 | 114 | /// Corresponding token. |
|
| 115 | 115 | tok: TokenKind, |
|
| 116 | 116 | } |
|
| 117 | 117 | ||
| 118 | 118 | /// Sorted keyword table for binary search. |
|
| 119 | - | const KEYWORDS: [Keyword; 53] = [ |
|
| 119 | + | const KEYWORDS: [Keyword; 52] = [ |
|
| 120 | 120 | { name: "align", tok: TokenKind::Align }, |
|
| 121 | 121 | { name: "and", tok: TokenKind::And }, |
|
| 122 | 122 | { name: "as", tok: TokenKind::As }, |
|
| 123 | 123 | { name: "assert", tok: TokenKind::Assert }, |
|
| 124 | 124 | { name: "bool", tok: TokenKind::Bool }, |
| 128 | 128 | { name: "const", tok: TokenKind::Const }, |
|
| 129 | 129 | { name: "constant", tok: TokenKind::Const }, |
|
| 130 | 130 | { name: "continue", tok: TokenKind::Continue }, |
|
| 131 | 131 | { name: "else", tok: TokenKind::Else }, |
|
| 132 | 132 | { name: "export", tok: TokenKind::Export }, |
|
| 133 | - | { name: "extern", tok: TokenKind::Extern }, |
|
| 134 | 133 | { name: "false", tok: TokenKind::False }, |
|
| 135 | 134 | { name: "fn", tok: TokenKind::Fn }, |
|
| 136 | 135 | { name: "for", tok: TokenKind::For }, |
|
| 137 | 136 | { name: "i16", tok: TokenKind::I16 }, |
|
| 138 | 137 | { name: "i32", tok: TokenKind::I32 }, |
test/tests/ecall.i64.rad
+1 -1
| 1 | 1 | //! returns: 0 |
|
| 2 | 2 | ||
| 3 | - | @intrinsic extern fn ecall(number: u32, arg1: i64, arg2: i64, arg3: i64, arg4: i64) -> i64; |
|
| 3 | + | @intrinsic fn ecall(number: u32, arg1: i64, arg2: i64, arg3: i64, arg4: i64) -> i64; |
|
| 4 | 4 | ||
| 5 | 5 | /// Test that ecall can pass and return i64 values. |
|
| 6 | 6 | @default fn main() -> i32 { |
|
| 7 | 7 | // ecall(64, fd, buf, len, 0) = write(fd, buf, len). |
|
| 8 | 8 | let msg: *[u8] = "ok\n"; |
test/tests/externfn.rad
+1 -1
| 1 | - | extern fn externalFunc(x: i32) -> i32; |
|
| 1 | + | fn externalFunc(x: i32) -> i32; |
test/tests/intrinsic.ebreak.rad
+1 -1
| 1 | 1 | //! Test intrinsic ebreak lowering. |
|
| 2 | 2 | ||
| 3 | - | @intrinsic extern fn ebreak(); |
|
| 3 | + | @intrinsic fn ebreak(); |
|
| 4 | 4 | ||
| 5 | 5 | fn test() { |
|
| 6 | 6 | ebreak(); |
|
| 7 | 7 | } |
test/tests/intrinsic.ecall.rad
+1 -1
| 1 | 1 | //! Test intrinsic ecall lowering. |
|
| 2 | 2 | ||
| 3 | - | @intrinsic extern fn ecall(num: u32, a0: i32, a1: i32, a2: i32, a3: i32) -> i32; |
|
| 3 | + | @intrinsic fn ecall(num: u32, a0: i32, a1: i32, a2: i32, a3: i32) -> i32; |
|
| 4 | 4 | ||
| 5 | 5 | fn test() -> i32 { |
|
| 6 | 6 | return ecall(64, 1, 100, 5, 0); |
|
| 7 | 7 | } |
vim/radiance.vim
+1 -1
| 14 | 14 | syntax match radianceComment "--.*$" |
|
| 15 | 15 | syntax keyword radianceTodo TODO FIXME contained containedin=radianceComment |
|
| 16 | 16 | ||
| 17 | 17 | " Keywords |
|
| 18 | 18 | syntax keyword radianceKeyword mod fn return if else while true false and or not case align static |
|
| 19 | - | syntax keyword radianceKeyword pub extern break continue use loop in for match nil undefined |
|
| 19 | + | syntax keyword radianceKeyword pub break continue use loop in for match nil undefined |
|
| 20 | 20 | syntax keyword radianceKeyword let mut as register device const log record union trait instance |
|
| 21 | 21 | syntax keyword radianceKeyword throws throw try catch panic assert super |
|
| 22 | 22 | syntax keyword radianceType i8 i16 i32 i64 u8 u16 u32 u64 f32 void bool bit opaque |
|
| 23 | 23 | ||
| 24 | 24 | " Double-quoted strings |