From e471cb95117f73e555ae9546f94e9b74db13f4e2 Mon Sep 17 00:00:00 2001 From: Marc Auberer Date: Tue, 23 Aug 2022 22:27:02 +0200 Subject: [PATCH] Distinguish between member and scope access operators (#189) * Adjust grammar * Add to parser * Add tests and adapt the existing ones * Update docs --- docs/docs/language/operator-precedence.md | 1 + media/test-project/os-test.spice | 10 +++++++++- src/Spice.g4 | 7 ++++--- src/analyzer/AnalyzerVisitor.cpp | 13 +++++++++++++ src/ast/AstNodes.h | 2 +- src/exception/SemanticError.cpp | 4 ++++ src/exception/SemanticError.h | 2 ++ src/generator/GeneratorVisitor.cpp | 8 ++++++++ src/parser/AstBuilderVisitor.cpp | 2 ++ std/builtin/builtin.spice | 2 +- std/type/int.spice | 12 ++++++++++++ .../error-generic-function-not-found/source.spice | 2 +- .../exception.out | 2 +- .../source.spice | 2 +- .../source.spice | 2 +- .../error-member-access-only-struct/exception.out | 1 + .../error-member-access-only-struct/source.spice | 4 ++++ .../error-scope-access-only-import/exception.out | 1 + .../error-scope-access-only-import/source.spice | 9 +++++++++ .../success-external-nested-struct/source.spice | 4 ++-- .../structs/success-external-structs/source.spice | 2 +- .../success-external-global-var/source.spice | 2 +- .../std/data/combined-test-1/source.spice | 6 +++--- .../std/data/pair-normal-usecase/source.spice | 2 +- .../std/data/queue-normal-usecase/source.spice | 2 +- .../std/data/stack-normal-usecase/source.spice | 2 +- .../std/data/triple-normal-usecase/source.spice | 2 +- .../std/data/vector-normal-usecase/source.spice | 2 +- .../std/io/mkdir-rmdir-direxists/source.spice | 2 +- test/test-files/std/os/os-name/source.spice | 2 +- 30 files changed, 90 insertions(+), 24 deletions(-) create mode 100644 test/test-files/analyzer/operators/error-member-access-only-struct/exception.out create mode 100644 test/test-files/analyzer/operators/error-member-access-only-struct/source.spice create mode 100644 test/test-files/analyzer/operators/error-scope-access-only-import/exception.out create mode 100644 test/test-files/analyzer/operators/error-scope-access-only-import/source.spice diff --git a/docs/docs/language/operator-precedence.md b/docs/docs/language/operator-precedence.md index 338340cc5..c63c0179d 100644 --- a/docs/docs/language/operator-precedence.md +++ b/docs/docs/language/operator-precedence.md @@ -8,6 +8,7 @@ The following table shows how Spice prioritizes the supported operators. The lis | ---------- | -------- | ------------------------------------ | ------------- | --------- | | 1 | `a()` | Function/procedure call | left to right | no | | 1 | `.` | Member access operator | left to right | no | +| 1 | `::` | Scope access operator | left to right | no | | 1 | `a[]` | Subscript operator | left to right | no | | 1 | `a++` | Postfix increment operator | left to right | yes | | 1 | `a--` | Postfix decrement operator | left to right | yes | diff --git a/media/test-project/os-test.spice b/media/test-project/os-test.spice index d8a725fa6..0168b9ecf 100644 --- a/media/test-project/os-test.spice +++ b/media/test-project/os-test.spice @@ -10,7 +10,7 @@ f main() { printf("Hello %s!", p1.getSecond()); }*/ -import "std/type/int" as integer; +/*import "std/type/int" as integer; const int vertexCount = 9; @@ -78,4 +78,12 @@ f main() { printf("Computing shortest paths with Dijkstra's algorithm ...\n"); dijkstra(graph, 0); printf("Done.\n"); +}*/ + +import "std/data/pair" as pair; + +f main() { + pair::Pair stringIntPair = pair::Pair("Test", 1234); + printf("First: %s\n", stringIntPair.getFirst()); + printf("Second: %d\n", stringIntPair.getSecond()); } \ No newline at end of file diff --git a/src/Spice.g4 b/src/Spice.g4 index 37a00409b..1ff097bfc 100644 --- a/src/Spice.g4 +++ b/src/Spice.g4 @@ -61,7 +61,7 @@ additiveExpr: multiplicativeExpr ((PLUS | MINUS) multiplicativeExpr)*; multiplicativeExpr: castExpr ((MUL | DIV | REM) castExpr)*; castExpr: prefixUnaryExpr | LPAREN dataType RPAREN prefixUnaryExpr; prefixUnaryExpr: prefixUnaryOp* postfixUnaryExpr; -postfixUnaryExpr: atomicExpr (LBRACKET assignExpr RBRACKET | DOT postfixUnaryExpr | PLUS_PLUS | MINUS_MINUS)*; +postfixUnaryExpr: atomicExpr (LBRACKET assignExpr RBRACKET | DOT postfixUnaryExpr | SCOPE_ACCESS postfixUnaryExpr | PLUS_PLUS | MINUS_MINUS)*; atomicExpr: value | IDENTIFIER | builtinCall | LPAREN assignExpr RPAREN; // Values and types @@ -69,11 +69,11 @@ value: primitiveValue | functionCall | arrayInitialization | structInstantiation primitiveValue: DOUBLE_LIT | INT_LIT | SHORT_LIT | LONG_LIT | CHAR_LIT | STRING_LIT | TRUE | FALSE; functionCall: IDENTIFIER (DOT IDENTIFIER)* (LESS typeLst GREATER)? LPAREN argLst? RPAREN; arrayInitialization: LBRACE argLst? RBRACE; -structInstantiation: IDENTIFIER (DOT IDENTIFIER)* (LESS typeLst GREATER)? LBRACE argLst? RBRACE; +structInstantiation: IDENTIFIER (SCOPE_ACCESS IDENTIFIER)* (LESS typeLst GREATER)? LBRACE argLst? RBRACE; dataType: baseDataType (MUL | LBRACKET (INT_LIT | assignExpr)? RBRACKET)*; baseDataType: TYPE_DOUBLE | TYPE_INT | TYPE_SHORT | TYPE_LONG | TYPE_BYTE | TYPE_CHAR | TYPE_STRING | TYPE_BOOL | TYPE_DYN | customDataType; -customDataType: IDENTIFIER (DOT IDENTIFIER)* (LESS typeLst GREATER)?; +customDataType: IDENTIFIER (SCOPE_ACCESS IDENTIFIER)* (LESS typeLst GREATER)?; // Shorthands assignOp: ASSIGN | PLUS_EQUAL | MINUS_EQUAL | MUL_EQUAL | DIV_EQUAL | REM_EQUAL | SHL_EQUAL | SHR_EQUAL | AND_EQUAL | OR_EQUAL | XOR_EQUAL; @@ -167,6 +167,7 @@ SEMICOLON: ';'; COLON: ':'; COMMA: ','; DOT: '.'; +SCOPE_ACCESS: '::'; ELLIPSIS: '...'; // Regex tokens diff --git a/src/analyzer/AnalyzerVisitor.cpp b/src/analyzer/AnalyzerVisitor.cpp index 839f9f628..3e2cfaecf 100644 --- a/src/analyzer/AnalyzerVisitor.cpp +++ b/src/analyzer/AnalyzerVisitor.cpp @@ -1629,6 +1629,19 @@ std::any AnalyzerVisitor::visitPostfixUnaryExpr(PostfixUnaryExprNode *node) { break; } case PostfixUnaryExprNode::OP_MEMBER_ACCESS: { + // Check if lhs is struct + if (!lhs.isBaseType(TY_STRUCT)) + throw err->get(node->codeLoc, MEMBER_ACCESS_ONLY_STRUCTS, "Cannot apply member access operator on " + lhs.getName()); + + PostfixUnaryExprNode *rhs = node->postfixUnaryExpr()[memberAccessCounter++]; + lhs = any_cast(visit(rhs)); // Visit rhs + break; + } + case PostfixUnaryExprNode::OP_SCOPE_ACCESS: { + // Check if lhs is import + if (!lhs.is(TY_IMPORT)) + throw err->get(node->codeLoc, SCOPE_ACCESS_ONLY_IMPORTS, "Cannot apply scope access operator on " + lhs.getName()); + PostfixUnaryExprNode *rhs = node->postfixUnaryExpr()[memberAccessCounter++]; lhs = any_cast(visit(rhs)); // Visit rhs break; diff --git a/src/ast/AstNodes.h b/src/ast/AstNodes.h index 44409fdf4..6a465fc98 100644 --- a/src/ast/AstNodes.h +++ b/src/ast/AstNodes.h @@ -996,7 +996,7 @@ class PrefixUnaryExprNode : public AstNode { class PostfixUnaryExprNode : public AstNode { public: // Enums - enum PostfixUnaryOp { OP_SUBSCRIPT, OP_MEMBER_ACCESS, OP_PLUS_PLUS, OP_MINUS_MINUS }; + enum PostfixUnaryOp { OP_SUBSCRIPT, OP_MEMBER_ACCESS, OP_PLUS_PLUS, OP_MINUS_MINUS, OP_SCOPE_ACCESS }; // Constructors using AstNode::AstNode; diff --git a/src/exception/SemanticError.cpp b/src/exception/SemanticError.cpp index 3726263c0..0621d6384 100644 --- a/src/exception/SemanticError.cpp +++ b/src/exception/SemanticError.cpp @@ -90,6 +90,10 @@ std::string SemanticError::getMessagePrefix(SemanticErrorType type) { return "Imported source file not existing"; case CIRCULAR_DEPENDENCY: return "Circular import detected"; + case MEMBER_ACCESS_ONLY_STRUCTS: + return "Member access is only allowed on structs"; + case SCOPE_ACCESS_ONLY_IMPORTS: + return "Scope access is only allowed on imports"; case UNKNOWN_DATATYPE: return "Unknown datatype"; case NUMBER_OF_FIELDS_NOT_MATCHING: diff --git a/src/exception/SemanticError.h b/src/exception/SemanticError.h index feda43352..a0a1dee5d 100644 --- a/src/exception/SemanticError.h +++ b/src/exception/SemanticError.h @@ -41,6 +41,8 @@ enum SemanticErrorType { DUPLICATE_IMPORT_NAME, IMPORTED_FILE_NOT_EXISTING, CIRCULAR_DEPENDENCY, + MEMBER_ACCESS_ONLY_STRUCTS, + SCOPE_ACCESS_ONLY_IMPORTS, UNKNOWN_DATATYPE, NUMBER_OF_FIELDS_NOT_MATCHING, FIELD_TYPE_NOT_MATCHING, diff --git a/src/generator/GeneratorVisitor.cpp b/src/generator/GeneratorVisitor.cpp index 3109f4d2b..5da063528 100644 --- a/src/generator/GeneratorVisitor.cpp +++ b/src/generator/GeneratorVisitor.cpp @@ -2236,6 +2236,14 @@ std::any GeneratorVisitor::visitPostfixUnaryExpr(PostfixUnaryExprNode *node) { lhs = nullptr; break; } + case PostfixUnaryExprNode::OP_SCOPE_ACCESS: { + // Visit identifier after the double colon + PostfixUnaryExprNode *rhs = node->postfixUnaryExpr()[memberAccessCounter++]; + lhsPtr = resolveAddress(rhs); + + lhs = nullptr; + break; + } case PostfixUnaryExprNode::OP_PLUS_PLUS: { if (!lhs) lhs = builder->CreateLoad(lhsTy, lhsPtr); diff --git a/src/parser/AstBuilderVisitor.cpp b/src/parser/AstBuilderVisitor.cpp index 0ca0452d3..aada89f7f 100644 --- a/src/parser/AstBuilderVisitor.cpp +++ b/src/parser/AstBuilderVisitor.cpp @@ -1131,6 +1131,8 @@ std::any AstBuilderVisitor::visitPostfixUnaryExpr(SpiceParser::PostfixUnaryExprC postfixUnaryExprNode->opQueue.emplace(PostfixUnaryExprNode::OP_PLUS_PLUS, SymbolType(TY_INVALID)); else if (auto t = dynamic_cast(subTree); t->getSymbol()->getType() == SpiceParser::MINUS_MINUS) postfixUnaryExprNode->opQueue.emplace(PostfixUnaryExprNode::OP_MINUS_MINUS, SymbolType(TY_INVALID)); + else if (auto t = dynamic_cast(subTree); t->getSymbol()->getType() == SpiceParser::SCOPE_ACCESS) + postfixUnaryExprNode->opQueue.emplace(PostfixUnaryExprNode::OP_SCOPE_ACCESS, SymbolType(TY_INVALID)); else assert(dynamic_cast(subTree)); // Fail if we did not get a terminal diff --git a/std/builtin/builtin.spice b/std/builtin/builtin.spice index a516e470a..113ce7f69 100644 --- a/std/builtin/builtin.spice +++ b/std/builtin/builtin.spice @@ -4,7 +4,7 @@ * @param condition Condition to check * @param message Message to print if the condition evaluates to false */ -public p assert(bool condition, string message = "") { +public p assertCondition(bool condition, string message = "") { if (!condition) { } diff --git a/std/type/int.spice b/std/type/int.spice index f73bb8312..58dcb5e55 100644 --- a/std/type/int.spice +++ b/std/type/int.spice @@ -2,6 +2,10 @@ public const int SIZE = 32; public const int MIN_VALUE = -2147483648; public const int MAX_VALUE = 2147483647; +const int nSmall = 100; +const string smallsString10 = "0123456789"; +const string smallsString100 = "00010203040506070809101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899"; + // Converts an int to a double public f toDouble(int input) { // ToDo: Implement @@ -37,4 +41,12 @@ public f toString(int input) { // Converts an int to a boolean public f toBool(int input) { return input >= 1; +} + +// Helper function: returns the string of a small number +f small(int i) { + if i < 10 { + return smallsString10.substring(i, i+1); + } + return smallsString100.substring(i*2, i*2+2); } \ No newline at end of file diff --git a/test/test-files/analyzer/generics/error-generic-function-not-found/source.spice b/test/test-files/analyzer/generics/error-generic-function-not-found/source.spice index 093b7ec4b..4dd67e73b 100644 --- a/test/test-files/analyzer/generics/error-generic-function-not-found/source.spice +++ b/test/test-files/analyzer/generics/error-generic-function-not-found/source.spice @@ -1,7 +1,7 @@ import "source1" as s1; f main() { - dyn v = s1.Vector{}; + dyn v = s1::Vector{}; v.setData(12); printf("Data: %d\n", v.data); v.setData(1.5); diff --git a/test/test-files/analyzer/imports/error-insufficient-global-var-visibility/exception.out b/test/test-files/analyzer/imports/error-insufficient-global-var-visibility/exception.out index e7e492550..37998092c 100644 --- a/test/test-files/analyzer/imports/error-insufficient-global-var-visibility/exception.out +++ b/test/test-files/analyzer/imports/error-insufficient-global-var-visibility/exception.out @@ -1 +1 @@ -Semantic error in ./test-files/analyzer/imports/error-insufficient-global-var-visibility/source.spice:4:33: Insufficient symbol visibility: Cannot access 'globalTestVar' due to its private visibility \ No newline at end of file +Semantic error in ./test-files/analyzer/imports/error-insufficient-global-var-visibility/source.spice:4:34: Insufficient symbol visibility: Cannot access 'globalTestVar' due to its private visibility \ No newline at end of file diff --git a/test/test-files/analyzer/imports/error-insufficient-global-var-visibility/source.spice b/test/test-files/analyzer/imports/error-insufficient-global-var-visibility/source.spice index d6bfc15af..8da2e7331 100644 --- a/test/test-files/analyzer/imports/error-insufficient-global-var-visibility/source.spice +++ b/test/test-files/analyzer/imports/error-insufficient-global-var-visibility/source.spice @@ -1,5 +1,5 @@ import "source1" as src1; f main() { - printf("Result: %d\n", src1.globalTestVar); + printf("Result: %d\n", src1::globalTestVar); } \ No newline at end of file diff --git a/test/test-files/analyzer/imports/error-insufficient-struct-visibility/source.spice b/test/test-files/analyzer/imports/error-insufficient-struct-visibility/source.spice index 9db6c94b9..8f2c8491c 100644 --- a/test/test-files/analyzer/imports/error-insufficient-struct-visibility/source.spice +++ b/test/test-files/analyzer/imports/error-insufficient-struct-visibility/source.spice @@ -1,6 +1,6 @@ import "source1" as s1; f main() { - dyn s = s1.Vector{1}; + dyn s = s1::Vector{1}; printf("Result: %d\n", s.i); } \ No newline at end of file diff --git a/test/test-files/analyzer/operators/error-member-access-only-struct/exception.out b/test/test-files/analyzer/operators/error-member-access-only-struct/exception.out new file mode 100644 index 000000000..03420e0bb --- /dev/null +++ b/test/test-files/analyzer/operators/error-member-access-only-struct/exception.out @@ -0,0 +1 @@ +Semantic error in ./test-files/analyzer/operators/error-member-access-only-struct/source.spice:3:5: Member access is only allowed on structs: Cannot apply member access operator on double \ No newline at end of file diff --git a/test/test-files/analyzer/operators/error-member-access-only-struct/source.spice b/test/test-files/analyzer/operators/error-member-access-only-struct/source.spice new file mode 100644 index 000000000..8f6bed3a5 --- /dev/null +++ b/test/test-files/analyzer/operators/error-member-access-only-struct/source.spice @@ -0,0 +1,4 @@ +f main() { + double doubleVar = 1.34; + doubleVar.test = 1; +} \ No newline at end of file diff --git a/test/test-files/analyzer/operators/error-scope-access-only-import/exception.out b/test/test-files/analyzer/operators/error-scope-access-only-import/exception.out new file mode 100644 index 000000000..49cf46840 --- /dev/null +++ b/test/test-files/analyzer/operators/error-scope-access-only-import/exception.out @@ -0,0 +1 @@ +Semantic error in ./test-files/analyzer/operators/error-scope-access-only-import/source.spice:8:5: Scope access is only allowed on imports: Cannot apply scope access operator on TestStruct \ No newline at end of file diff --git a/test/test-files/analyzer/operators/error-scope-access-only-import/source.spice b/test/test-files/analyzer/operators/error-scope-access-only-import/source.spice new file mode 100644 index 000000000..8b794d236 --- /dev/null +++ b/test/test-files/analyzer/operators/error-scope-access-only-import/source.spice @@ -0,0 +1,9 @@ +type TestStruct struct { + int t1 + double* t2 +} + +f main() { + dyn ts = TestStruct{}; + ts::t1 = 2; +} \ No newline at end of file diff --git a/test/test-files/generator/structs/success-external-nested-struct/source.spice b/test/test-files/generator/structs/success-external-nested-struct/source.spice index 3952a1642..32c7e2bfe 100644 --- a/test/test-files/generator/structs/success-external-nested-struct/source.spice +++ b/test/test-files/generator/structs/success-external-nested-struct/source.spice @@ -1,8 +1,8 @@ import "source1" as socket; f main() { - socket.Socket s = socket.openServerSocket(8080s); - socket.NestedSocket n = s.nested; + socket::Socket s = socket.openServerSocket(8080s); + socket::NestedSocket n = s.nested; printf("Test string: %s\n", n.testString); printf("Socket: %d\n", s.sock); } \ No newline at end of file diff --git a/test/test-files/generator/structs/success-external-structs/source.spice b/test/test-files/generator/structs/success-external-structs/source.spice index cf4ad8425..6a3fd91d7 100644 --- a/test/test-files/generator/structs/success-external-structs/source.spice +++ b/test/test-files/generator/structs/success-external-structs/source.spice @@ -1,6 +1,6 @@ import "source1" as s1; f main() { - dyn v = s1.Vec{11, false}; + dyn v = s1::Vec{11, false}; v.print(); } \ No newline at end of file diff --git a/test/test-files/generator/variables/success-external-global-var/source.spice b/test/test-files/generator/variables/success-external-global-var/source.spice index 3e9a4e840..5e07be813 100644 --- a/test/test-files/generator/variables/success-external-global-var/source.spice +++ b/test/test-files/generator/variables/success-external-global-var/source.spice @@ -1,5 +1,5 @@ import "source1" as s1; f main() { - printf("Global var: %s\n", s1.GLOBAL); + printf("Global var: %s\n", s1::GLOBAL); } \ No newline at end of file diff --git a/test/test-files/std/data/combined-test-1/source.spice b/test/test-files/std/data/combined-test-1/source.spice index cc78e1bca..4bfd26e9d 100644 --- a/test/test-files/std/data/combined-test-1/source.spice +++ b/test/test-files/std/data/combined-test-1/source.spice @@ -2,7 +2,7 @@ import "std/data/vector" as vec; import "std/data/pair" as pair; f main() { - vec.Vector> pairVector = vec.Vector>(); - pairVector.pushBack(pair.Pair(0, "Hello")); - pairVector.pushBack(pair.Pair(1, "World")); + vec::Vector> pairVector = vec::Vector>(); + pairVector.pushBack(pair::Pair(0, "Hello")); + pairVector.pushBack(pair::Pair(1, "World")); } \ No newline at end of file diff --git a/test/test-files/std/data/pair-normal-usecase/source.spice b/test/test-files/std/data/pair-normal-usecase/source.spice index 82abb1bba..55697af58 100644 --- a/test/test-files/std/data/pair-normal-usecase/source.spice +++ b/test/test-files/std/data/pair-normal-usecase/source.spice @@ -1,7 +1,7 @@ import "std/data/pair" as pair; f main() { - pair.Pair stringIntPair = pair.Pair("Test", 1234); + pair::Pair stringIntPair = pair::Pair("Test", 1234); printf("First: %s\n", stringIntPair.getFirst()); printf("Second: %d\n", stringIntPair.getSecond()); } \ No newline at end of file diff --git a/test/test-files/std/data/queue-normal-usecase/source.spice b/test/test-files/std/data/queue-normal-usecase/source.spice index 3ae1f83c1..867f6ef3a 100644 --- a/test/test-files/std/data/queue-normal-usecase/source.spice +++ b/test/test-files/std/data/queue-normal-usecase/source.spice @@ -1,7 +1,7 @@ import "std/data/queue" as que; f main() { - dyn q1 = que.Queue(); + dyn q1 = que::Queue(); q1.push('H'); q1.push('e'); q1.push('l'); diff --git a/test/test-files/std/data/stack-normal-usecase/source.spice b/test/test-files/std/data/stack-normal-usecase/source.spice index 7969d6be2..3778e3c9a 100644 --- a/test/test-files/std/data/stack-normal-usecase/source.spice +++ b/test/test-files/std/data/stack-normal-usecase/source.spice @@ -1,7 +1,7 @@ import "std/data/stack" as stc; f main() { - stc.Stack s1 = stc.Stack{}; + stc::Stack s1 = stc::Stack{}; s1.ctor(); s1.push(123); s1.push(456); diff --git a/test/test-files/std/data/triple-normal-usecase/source.spice b/test/test-files/std/data/triple-normal-usecase/source.spice index 4331de712..f4a413d4b 100644 --- a/test/test-files/std/data/triple-normal-usecase/source.spice +++ b/test/test-files/std/data/triple-normal-usecase/source.spice @@ -1,7 +1,7 @@ import "std/data/triple" as triple; f main() { - triple.Triple stringIntBoolTriple = triple.Triple("Test", 1234, true); + triple::Triple stringIntBoolTriple = triple::Triple("Test", 1234, true); printf("First: %s\n", stringIntBoolTriple.getFirst()); printf("Second: %d\n", stringIntBoolTriple.getSecond()); printf("Third: %d\n", stringIntBoolTriple.getThird()); diff --git a/test/test-files/std/data/vector-normal-usecase/source.spice b/test/test-files/std/data/vector-normal-usecase/source.spice index f5842c9ba..50af1fd1e 100644 --- a/test/test-files/std/data/vector-normal-usecase/source.spice +++ b/test/test-files/std/data/vector-normal-usecase/source.spice @@ -1,7 +1,7 @@ import "std/data/vector" as vec; f main() { - vec.Vector v1 = vec.Vector(3); + vec::Vector v1 = vec::Vector(3); v1.pushBack(1.2); v1.pushBack(7.4964598); v1.pushBack(5.3); diff --git a/test/test-files/std/io/mkdir-rmdir-direxists/source.spice b/test/test-files/std/io/mkdir-rmdir-direxists/source.spice index 1817a0424..fc8fa8e74 100644 --- a/test/test-files/std/io/mkdir-rmdir-direxists/source.spice +++ b/test/test-files/std/io/mkdir-rmdir-direxists/source.spice @@ -2,7 +2,7 @@ import "std/io/dir" as dir; f main() { printf("Existing before create: %d\n", dir.dirExists("./test")); - dyn mkReturnCode = dir.mkDir("./test", dir.MODE_ALL_RWX); + dyn mkReturnCode = dir.mkDir("./test", dir::MODE_ALL_RWX); printf("mkDir return code: %d\n", mkReturnCode); printf("Existing after create: %d\n", dir.dirExists("./test")); dyn rmReturnCode = dir.rmDir("./test"); diff --git a/test/test-files/std/os/os-name/source.spice b/test/test-files/std/os/os-name/source.spice index 82ce32d5d..391921cf7 100644 --- a/test/test-files/std/os/os-name/source.spice +++ b/test/test-files/std/os/os-name/source.spice @@ -1,5 +1,5 @@ import "std/os/os" as os; f main() { - printf("OS name: %s", os.OS_NAME); + printf("OS name: %s", os::OS_NAME); } \ No newline at end of file