From 9f4356d596e6c892ccf76df1fe30f6820de5294f Mon Sep 17 00:00:00 2001 From: Benoit Giannangeli Date: Mon, 11 Mar 2024 12:10:14 +0100 Subject: [PATCH] feat: Namespace - A script exporting at least one symbol, must specify its namespace at the start of the script - When importing, the namespace can be changed with `as` - A `_` import namespace will erase the imported symbols namespace closes #271 --- build.zig | 2 +- examples/game-of-life.buzz | 10 +- examples/sdl-wrapped.buzz | 12 +- examples/sdl.buzz | 2 +- examples/sqlite.buzz | 41 +++---- src/Ast.zig | 3 + src/Codegen.zig | 3 +- src/Parser.zig | 114 +++++++++++++----- src/Token.zig | 76 ++++++------ src/lib/buffer.buzz | 35 +++--- src/lib/buzz_serialize.zig | 2 +- src/lib/crypto.buzz | 2 + src/lib/debug.buzz | 3 +- src/lib/errors.buzz | 2 + src/lib/ffi.buzz | 2 + src/lib/fs.buzz | 24 ++-- src/lib/gc.buzz | 2 + src/lib/http.buzz | 16 +-- src/lib/io.buzz | 24 ++-- src/lib/math.buzz | 4 +- src/lib/os.buzz | 32 ++--- src/lib/serialize.buzz | 26 ++-- src/lib/std.buzz | 2 + src/lib/{test.buzz => testing.buzz} | 21 ++-- src/scanner.zig | 1 + tests/001-basic-types.buzz | 14 +-- tests/002-operators.buzz | 42 +++---- tests/003-control-flow.buzz | 22 ++-- tests/004-lists.buzz | 34 +++--- tests/005-maps.buzz | 34 +++--- tests/006-enums.buzz | 16 +-- tests/007-objects.buzz | 10 +- tests/008-inline-catch.buzz | 2 +- tests/009-gc.buzz | 4 +- tests/010-placeholder-cycle.buzz | 4 +- tests/011-list-map-properties.buzz | 4 +- tests/012-lambda.buzz | 10 +- tests/014-import-lib.buzz | 4 +- tests/015-interpolation.buzz | 10 +- tests/016-optionals.buzz | 14 +-- tests/017-for.buzz | 4 +- tests/018-foreach.buzz | 18 +-- tests/019-is.buzz | 18 +-- tests/021-upvalues.buzz | 2 +- tests/022-io.buzz | 18 +-- tests/023-std.buzz | 24 ++-- tests/024-os.buzz | 10 +- tests/025-fs.buzz | 12 +- tests/026-break-continue.buzz | 4 +- tests/027-run-file.buzz | 8 +- tests/028-math.buzz | 30 ++--- tests/029-default-arguments.buzz | 10 +- tests/030-str.buzz | 28 ++--- tests/031-json.buzz | 12 +- tests/032-debug.buzz | 4 +- tests/033-invoke.buzz | 2 +- tests/034-scope.buzz | 14 +-- tests/035-const-expr.buzz | 18 +-- tests/036-pattern.buzz | 18 +-- tests/037-dead-branches.buzz | 10 +- tests/038-fibers.buzz | 20 +-- tests/039-buffer.buzz | 18 +-- tests/040-bitwise.buzz | 12 +- tests/041-iterator.buzz | 4 +- tests/042-anonymous-objects.buzz | 6 +- tests/044-break-continue.buzz | 4 +- tests/045-mutual-import.buzz | 8 +- tests/046-try-catch.buzz | 20 +-- tests/047-if-arrow.buzz | 4 +- tests/048-generics.buzz | 18 +-- tests/049-multiline-strings.buzz | 6 +- tests/050-protocols.buzz | 10 +- tests/051-functional.buzz | 20 +-- tests/052-inline-if.buzz | 8 +- tests/053-range.buzz | 8 +- tests/056-crypto.buzz | 10 +- tests/057-any.buzz | 20 +-- tests/058-ffi.buzz | 56 ++++----- tests/059-types-as-value.buzz | 34 +++--- tests/060-free-identifiers.buzz | 4 +- tests/061-utf8.buzz | 8 +- tests/063-nullable-default.buzz | 4 +- tests/064-throw-inside-try.buzz | 4 +- tests/065-inferred-var-type.buzz | 8 +- tests/066-object-generics.buzz | 4 +- tests/068-testing.buzz | 4 +- tests/069-named-expr.buzz | 4 +- tests/070-block-expression.buzz | 6 +- tests/071-tail-call.buzz | 6 +- tests/bench/001-btree.buzz | 19 ++- tests/bench/002-merkle.buzz | 20 ++- tests/bench/003-nbody.buzz | 8 +- tests/bench/004-spectral.buzz | 14 +-- tests/bench/005-k-nucleoide.buzz | 12 +- tests/bench/006-fasta.buzz | 30 ++--- tests/bench/007-fib.buzz | 2 +- tests/bench/008-for.buzz | 6 +- tests/bench/009-grid.buzz | 6 +- tests/bench/010-ackermann.buzz | 6 +- tests/bench/011-bubble-sort.buzz | 4 +- tests/compile_errors/006-deep-yield.buzz | 2 +- .../compile_errors/010-multiple-location.buzz | 2 +- .../021-fiber-error-location.buzz | 2 +- tests/compile_errors/027-early-return.buzz | 4 +- tests/manual/001-cli-args.buzz | 2 +- tests/manual/002-error.buzz | 2 +- tests/manual/003-io.buzz | 6 +- tests/manual/004-os.buzz | 2 +- tests/manual/005-tcp-client.buzz | 6 +- ...-http-client.buzz => 006-http-client.buzz} | 10 +- tests/manual/006-tcp-server.buzz | 30 ----- tests/utils/import-a.buzz | 2 + tests/utils/import-b.buzz | 6 +- tests/utils/testing.buzz | 2 + 114 files changed, 772 insertions(+), 720 deletions(-) rename src/lib/{test.buzz => testing.buzz} (93%) rename tests/manual/{007-http-client.buzz => 006-http-client.buzz} (58%) delete mode 100644 tests/manual/006-tcp-server.buzz diff --git a/build.zig b/build.zig index 484c0239..12467791 100644 --- a/build.zig +++ b/build.zig @@ -442,7 +442,7 @@ pub fn build(b: *Build) !void { .{ .name = "http", .path = "src/lib/buzz_http.zig", .wasm_compatible = false }, .{ .name = "ffi", .path = "src/lib/buzz_ffi.zig", .wasm_compatible = false }, .{ .name = "serialize", .path = "src/lib/buzz_serialize.zig" }, - .{ .name = "test", .path = null }, + .{ .name = "testing", .path = null }, .{ .name = "errors", .path = null }, }; diff --git a/examples/game-of-life.buzz b/examples/game-of-life.buzz index 7b67f7b7..5513804c 100644 --- a/examples/game-of-life.buzz +++ b/examples/game-of-life.buzz @@ -1,8 +1,8 @@ import "std"; -import "io" as io; +import "io"; import "os"; import "debug"; -import "examples/sdl-wrapped"; +import "examples/sdl-wrapped" as _; | buzz -L/path/to/SDL2.dylib/so/dll examples/game-of-life.buzz object World { @@ -18,7 +18,7 @@ object World { }; for (int i = 0; i < width * height; i = i + 1) { - world.cells.append(random(max: 5) == 1); + world.cells.append(std.random(max: 5) == 1); } return world; @@ -156,8 +156,8 @@ fun main([str] args) > void !> SDLError { height: 600, ); - int? width = if (args.len() > 0) parseInt(args[0]) else null; - int? height = if (args.len() > 1) parseInt(args[1]) else null; + int? width = if (args.len() > 0) std.parseInt(args[0]) else null; + int? height = if (args.len() > 1) std.parseInt(args[1]) else null; var world = World.init( width: width ?? 10, diff --git a/examples/sdl-wrapped.buzz b/examples/sdl-wrapped.buzz index 16532e2d..e717ff73 100644 --- a/examples/sdl-wrapped.buzz +++ b/examples/sdl-wrapped.buzz @@ -1,3 +1,5 @@ +namespace sdl; + import "std"; import "ffi"; @@ -212,7 +214,7 @@ export object SDL { flags = flags \ subsystem.value; } - if (SDL_Init(toFloat(flags)) != 0) { + if (SDL_Init(std.toFloat(flags)) != 0) { throw SDLError{ message = "SDL_Init error: {SDL_GetError()}", }; @@ -293,7 +295,7 @@ export object Renderer { ) > Texture !> SDLError { const SDL_Texture? texture = SDL_CreateTexture( this.renderer, - format: toFloat(format.value), + format: std.toFloat(format.value), access: access.value, w: width, h: height, @@ -415,12 +417,12 @@ export object Window { } const SDL_Window? window = SDL_CreateWindow( - cstr(name), + ffi.cstr(name), x, y, w: width, h: height, - flags: toFloat(windowFlags), + flags: std.toFloat(windowFlags), ); if (window -> unwrapped) { @@ -446,7 +448,7 @@ export object Window { const SDL_Renderer? renderer = SDL_CreateRenderer( this.window, index: index, - flags: toFloat(rendererFlags), + flags: std.toFloat(rendererFlags), ); if (renderer -> unwrapped) { diff --git a/examples/sdl.buzz b/examples/sdl.buzz index 11b9fc59..7ccc42eb 100644 --- a/examples/sdl.buzz +++ b/examples/sdl.buzz @@ -1,5 +1,5 @@ import "std"; -import "examples/sdl-wrapped"; +import "examples/sdl-wrapped" as _; | buzz -L/path/to/SDL2.dylib/so/dll examples/sdl.buzz fun main([str] args) > int !> SDLError { diff --git a/examples/sqlite.buzz b/examples/sqlite.buzz index 16100dcd..c6ab35f6 100644 --- a/examples/sqlite.buzz +++ b/examples/sqlite.buzz @@ -1,8 +1,9 @@ +namespace sqlite; + import "ffi"; import "std"; -import "buffer"; -import "serialize"; -import "log"; +import "buffer" as _; +import "serialize" as _; zdef("sqlite3", ` fn sqlite3_initialize() c_int; @@ -152,7 +153,7 @@ export object Statement { ud stmt, fun execute() > [[Boxed]] *> [Boxed]? !> SQLiteError { - Logger.instance?.debug("Executing query `{this.query}`", namespace: "SQL"); + std.print("Executing query `{this.query}`"); ResultCode code = ResultCode.Ok; [[Boxed]] rows = [<[Boxed]>]; @@ -198,14 +199,14 @@ export object Statement { const [Boxed] boxedRow = (Boxed.init(row) catch void).listValue(); rows.append(boxedRow); - yield boxedRow; + _ = yield boxedRow; } return rows; } fun collect() > void { - sqlite3_finalize(this.stmt); + _ = sqlite3_finalize(this.stmt); } } @@ -213,13 +214,7 @@ export object Database { ud db, fun collect() > void { - const ResultCode code = ResultCode(sqlite3_close_v2(this.db)) ?? ResultCode.Error; - if (code != ResultCode.Ok) { - throw SQLiteError{ - code = code, - message = "Could not close database: {code} {sqlite3_errmsg(this.db)}" - }; - } + _ = ResultCode(sqlite3_close_v2(this.db)) ?? ResultCode.Error; } fun prepare(Query query) > Statement !> SQLiteError { @@ -228,12 +223,12 @@ export object Database { fun prepareRaw(str query) > Statement !> SQLiteError { Buffer buffer = Buffer.init(); - buffer.writeUserData(toUd(0)) catch void; + buffer.writeUserData(std.toUd(0)) catch void; const ResultCode code = ResultCode( sqlite3_prepare_v2( db: this.db, - zSql: cstr(query), + zSql: ffi.cstr(query), nBytes: -1, ppStmt: buffer.ptr(), pzTail: null, @@ -268,11 +263,11 @@ export object SQLite { } static fun escape(str string) > str { - return sqlite3_mprintf(cstr(string)) ?? ""; + return sqlite3_mprintf(ffi.cstr(string)) ?? ""; } fun collect() > void { - sqlite3_shutdown(); + _ = sqlite3_shutdown(); } fun open(str filename, [OpenFlag] flags) > Database !> SQLiteError { @@ -282,11 +277,11 @@ export object SQLite { } Buffer buffer = Buffer.init(); - buffer.writeUserData(toUd(0)) catch void; + buffer.writeUserData(std.toUd(0)) catch void; const ResultCode code = ResultCode( sqlite3_open_v2( - filename: cstr(filename), + filename: ffi.cstr(filename), ppDb: buffer.ptr(), flags: cFlags, zVfs: null @@ -300,7 +295,7 @@ export object SQLite { }; } - Logger.instance?.info("Database `{filename}` opened", namespace: "SQL"); + std.print("Database `{filename}` opened"); return Database { db = buffer.readUserData()!, @@ -319,10 +314,10 @@ test "Testing sqlite" { ) `); - statement.execute(); + _ = statement.execute(); foreach (str name in ["john", "joe", "janet", "joline"]) { - Query{} + _ = Query{} .insertInto("test", columns: [ "name" ]) .values([ "'{name}'" ]) .execute(database); @@ -334,6 +329,6 @@ test "Testing sqlite" { .prepare(database); foreach ([Boxed] row in &select.execute()) { - print("{row[0].integerValue()}: {row[1].stringValue()}"); + std.print("{row[0].integerValue()}: {row[1].stringValue()}"); } } \ No newline at end of file diff --git a/src/Ast.zig b/src/Ast.zig index 0f9fa766..5398902d 100644 --- a/src/Ast.zig +++ b/src/Ast.zig @@ -109,6 +109,7 @@ pub const Node = struct { ListType, Map, MapType, + Namespace, NamedVariable, Null, ObjectDeclaration, @@ -174,6 +175,7 @@ pub const Node = struct { ListType: ListType, Map: Map, MapType: MapType, + Namespace: TokenIndex, NamedVariable: NamedVariable, Null: void, ObjectDeclaration: ObjectDeclaration, @@ -562,6 +564,7 @@ pub fn isConstant(self: Self, node: Node.Index) bool { .StringLiteral, .TypeExpression, .Void, + .Namespace, => true, .AsyncCall, .Block, diff --git a/src/Codegen.zig b/src/Codegen.zig index 9257a691..2880252a 100644 --- a/src/Codegen.zig +++ b/src/Codegen.zig @@ -58,7 +58,7 @@ jit: ?*JIT, reporter: Reporter, const generators = [_]NodeGen{ - &noGen, // AnonymousObjectType, + noGen, // AnonymousObjectType, generateAs, // As, generateAsyncCall, // AsyncCall, generateBinary, // Binary, @@ -93,6 +93,7 @@ const generators = [_]NodeGen{ noGen, // ListType, generateMap, // Map, noGen, // MapType, + noGen, // Namespace, generateNamedVariable, // NamedVariable, generateNull, // Null, generateObjectDeclaration, // ObjectDeclaration, diff --git a/src/Parser.zig b/src/Parser.zig index dc7ad0b1..05354a82 100644 --- a/src/Parser.zig +++ b/src/Parser.zig @@ -184,8 +184,8 @@ pub const Local = struct { }; pub const Global = struct { - prefix: ?[]const u8 = null, - name: *obj.ObjString, // TODO: do i need to mark those? does it need to be an objstring? + prefix: ?[]const u8, + name: *obj.ObjString, name_token: Ast.TokenIndex, location: Ast.TokenIndex, type_def: *obj.ObjTypeDef, @@ -461,6 +461,7 @@ const rules = [_]ParseRule{ .{ .prefix = typeOfExpression, .infix = null, .precedence = .Unary }, // typeof .{ .prefix = null, .infix = null, .precedence = .None }, // var .{ .prefix = null, .infix = null, .precedence = .None }, // out + .{ .prefix = null, .infix = null, .precedence = .None }, // namespace }; ast: Ast, @@ -478,8 +479,8 @@ test_count: u64 = 0, // FIXME: use SinglyLinkedList instead of heap allocated ptrs current: ?*Frame = null, current_object: ?ObjectFrame = null, -// TODO: make this a multiarray? globals: std.ArrayList(Global), +namespace: ?[]const u8 = null, flavor: RunFlavor, ffi: FFI, reporter: Reporter, @@ -857,7 +858,7 @@ pub fn parse(self: *Self, source: []const u8, file_name: []const u8) !?Ast { // Then put any exported globals on the stack if (function_type == .ScriptEntryPoint) { for (self.globals.items, 0..) |global, index| { - if (std.mem.eql(u8, global.name.string, "main") and !global.hidden and global.prefix == null) { + if (std.mem.eql(u8, global.name.string, "main") and !global.hidden and (self.namespace == null or global.prefix == null or std.mem.eql(u8, global.prefix.?, self.namespace.?))) { entry.main_slot = index; entry.main_location = global.location; break; @@ -1365,6 +1366,8 @@ fn declaration(self: *Self) Error!?Ast.Node.Index { break :user_decl null; } else if (global_scope and !constant and try self.match(.Export)) try self.exportStatement() + else if (global_scope and !constant and try self.match(.Namespace)) + try self.namespaceStatement() else null; @@ -1432,12 +1435,15 @@ fn statement(self: *Self, hanging: bool, loop_scope: ?LoopScope) !?Ast.Node.Inde } else if (try self.match(.Out)) { std.debug.assert(!hanging); return try self.outStatement(); + } else if (try self.match(.Namespace)) { + std.debug.assert(!hanging); + return try self.namespaceStatement(); } else if (try self.match(.Throw)) { const start_location = self.current_token.? - 1; // For now we don't care about the type. Later if we have `Error` type of data, we'll type check this const error_value = try self.expression(false); - try self.consume(.Semicolon, "Expected `;` after `throw` expression."); + try self.consume(.Semicolon, "Expected `;` after statement."); return try self.ast.appendNode( .{ @@ -1507,6 +1513,7 @@ fn addGlobal(self: *Self, name: Ast.TokenIndex, global_type: *obj.ObjTypeDef, co try self.globals.append( Global{ + .prefix = self.namespace, .name_token = name, .name = try self.gc.copyString(lexemes[name]), .location = name, @@ -1572,7 +1579,17 @@ pub fn resolveGlobal(self: *Self, prefix: ?[]const u8, name: []const u8) Error!? var i: usize = self.globals.items.len - 1; while (i >= 0) : (i -= 1) { const global: *Global = &self.globals.items[i]; - if (((prefix == null and global.prefix == null) or (prefix != null and global.prefix != null and std.mem.eql(u8, prefix.?, global.prefix.?))) and std.mem.eql(u8, name, global.name.string) and !global.hidden) { + // zig fmt: off + if ( + ( + global.prefix == null // Not prefixed + or (prefix != null and std.mem.eql(u8, prefix.?, global.prefix.?)) // Same prefix as provided + or (self.namespace != null and std.mem.eql(u8, global.prefix.?, self.namespace.?)) // Prefix is the current namespace + ) + and std.mem.eql(u8, name, global.name.string) + and !global.hidden + ) { + // zig fmt: on if (!global.initialized) { self.reportErrorFmt( .global_initializer, @@ -5701,11 +5718,11 @@ fn funDeclaration(self: *Self) Error!Ast.Node.Index { const fun_typedef = self.ast.nodes.items(.type_def)[function_node].?; if (fun_typedef.resolved_type.?.Function.lambda) { - try self.consume(.Semicolon, "Expected `;` after lambda function"); + try self.consume(.Semicolon, "Expected `;` after statement"); } if (function_type == .Extern) { - try self.consume(.Semicolon, "Expected `;` after `extern` function declaration."); + try self.consume(.Semicolon, "Expected `;` after statement."); } // Enforce main signature @@ -5766,26 +5783,32 @@ fn funDeclaration(self: *Self) Error!Ast.Node.Index { fn exportStatement(self: *Self) Error!Ast.Node.Index { const start_location = self.current_token.? - 1; + if (self.namespace == null) { + self.reportError(.syntax, "A exporting script must provide a namespace"); + } + if (self.check(.Identifier) and (try self.checkAhead(.Semicolon, 0) or try self.checkAhead(.As, 0) or try self.checkAhead(.Dot, 0))) { try self.consume(.Identifier, "Expected identifier after `export`."); const identifier = self.current_token.? - 1; // Search for a global with that name if (try self.resolveGlobal(null, self.ast.tokens.items(.lexeme)[identifier])) |slot| { - const global: *Global = &self.globals.items[slot]; + const global = &self.globals.items[slot]; global.referenced = true; var alias: ?Ast.TokenIndex = null; global.exported = true; - if (global.prefix != null or self.check(.As)) { - try self.consume(.As, "Expected `as` after prefixed global."); + if (try self.match(.As)) { try self.consume(.Identifier, "Expected identifier after `as`."); global.export_alias = self.ast.tokens.items(.lexeme)[self.current_token.? - 1]; alias = self.current_token.? - 1; } - try self.consume(.Semicolon, "Expected `;` after export."); + // If we're exporting an imported global, overwrite is prefix + global.prefix = self.namespace; + + try self.consume(.Semicolon, "Expected `;` after statement."); return try self.ast.appendNode( .{ @@ -6670,7 +6693,7 @@ fn varDeclaration( switch (terminator) { .OptComma => _ = try self.match(.Comma), .Comma => try self.consume(.Comma, "Expected `,` after variable declaration."), - .Semicolon => try self.consume(.Semicolon, "Expected `;` after variable declaration."), + .Semicolon => try self.consume(.Semicolon, "Expected `;` after statement."), .Nothing => {}, } @@ -7141,18 +7164,16 @@ fn importScript( for (parser.globals.items) |*global| { if (global.exported) { - global.*.exported = false; + global.exported = false; if (global.export_alias) |export_alias| { - global.*.name = try self.gc.copyString(export_alias); - global.*.export_alias = null; + global.name = try self.gc.copyString(export_alias); + global.export_alias = null; } } else { - global.*.hidden = true; + global.hidden = true; } - global.*.prefix = prefix; - try import.?.globals.append(global.*); } @@ -7170,7 +7191,9 @@ fn importScript( if (import) |imported| { const selective_import = imported_symbols.count() > 0; - for (imported.globals.items) |*global| { + for (imported.globals.items) |imported_global| { + var global = imported_global; + if (!global.hidden) { if (imported_symbols.get(global.name.string) != null) { _ = imported_symbols.remove(global.name.string); @@ -7190,12 +7213,15 @@ fn importScript( ); } - global.*.prefix = prefix; + global.prefix = if (prefix != null and std.mem.eql(u8, "_", prefix.?)) + null // import "..." as _; | Erased prefix so the imported global are in the importer script namespace + else + prefix orelse global.prefix; } // TODO: we're forced to import all and hide some because globals are indexed and not looked up by name at runtime // Only way to avoid this is to go back to named globals at runtime. Then again, is it worth it? - try self.globals.append(global.*); + try self.globals.append(global); } } else { // TODO: when it cannot load dynamic library, the error is the same @@ -7384,12 +7410,15 @@ fn importStatement(self: *Self) Error!Ast.Node.Index { prefix = self.current_token.? - 1; } - try self.consume(.Semicolon, "Expected `;` after import."); + try self.consume(.Semicolon, "Expected `;` after statement."); const import = if (!self.reporter.had_error) try self.importScript( file_name, - if (prefix) |pr| self.ast.tokens.items(.lexeme)[pr] else null, + if (prefix) |pr| + self.ast.tokens.items(.lexeme)[pr] + else + null, &imported_symbols, ) else @@ -7962,7 +7991,7 @@ fn returnStatement(self: *Self) Error!Ast.Node.Index { null; if (value) |uvalue| { - try self.consume(.Semicolon, "Expected `;` after return value."); + try self.consume(.Semicolon, "Expected `;` after statement."); // Tail call (TODO: do it for dot call) if (self.ast.nodes.items(.tag)[uvalue] == .Call) { @@ -8004,7 +8033,7 @@ fn outStatement(self: *Self) Error!Ast.Node.Index { const expr = try self.expression(false); - try self.consume(.Semicolon, "Expected `;` after `out` statement."); + try self.consume(.Semicolon, "Expected `;` after statement."); return try self.ast.appendNode( .{ @@ -8019,6 +8048,35 @@ fn outStatement(self: *Self) Error!Ast.Node.Index { ); } +fn namespaceStatement(self: *Self) Error!Ast.Node.Index { + const start_location = self.current_token.? - 1; + + // Should be the first statement + const components = self.ast.nodes.items(.components); + const current_body = components[self.current.?.function_node].Function.body; + if (current_body == null or components[current_body.?].Block.len > 0) { + self.reportError(.syntax, "`namespace` should be the first statement"); + } + + try self.consume(.Identifier, "Expected namespace identifier"); + + const identifier = self.current_token.? - 1; + self.namespace = self.ast.tokens.items(.lexeme)[identifier]; + + try self.consume(.Semicolon, "Expected `;` after statement."); + + return try self.ast.appendNode( + .{ + .tag = .Namespace, + .location = start_location, + .end_location = self.current_token.? - 1, + .components = .{ + .Namespace = identifier, + }, + }, + ); +} + fn tryStatement(self: *Self) Error!Ast.Node.Index { const start_location = self.current_token.? - 1; @@ -8107,7 +8165,7 @@ fn breakStatement(self: *Self, loop_scope: ?LoopScope) Error!Ast.Node.Index { self.reportError(.syntax, "break is not allowed here."); } - try self.consume(.Semicolon, "Expected `;` after `break`."); + try self.consume(.Semicolon, "Expected `;` after statement."); return try self.ast.appendNode( .{ @@ -8132,7 +8190,7 @@ fn continueStatement(self: *Self, loop_scope: ?LoopScope) Error!Ast.Node.Index { self.reportError(.syntax, "continue is not allowed here."); } - try self.consume(.Semicolon, "Expected `;` after `continue`."); + try self.consume(.Semicolon, "Expected `;` after statement."); return try self.ast.appendNode( .{ diff --git a/src/Token.zig b/src/Token.zig index 73471814..d9b69ade 100644 --- a/src/Token.zig +++ b/src/Token.zig @@ -176,63 +176,65 @@ pub const Type = enum { TypeOf, // typeof Var, // var Out, // out + Namespace, // namespace }; pub const keywords = std.ComptimeStringMap( Type, .{ - .{ "ud", .Ud }, - .{ "void", .Void }, - .{ "true", .True }, - .{ "false", .False }, - .{ "null", .Null }, - .{ "or", .Or }, .{ "and", .And }, + .{ "any", .Any }, .{ "as", .As }, - .{ "return", .Return }, - .{ "if", .If }, - .{ "else", .Else }, - .{ "while", .While }, - .{ "for", .For }, - .{ "foreach", .ForEach }, - .{ "switch", .Switch }, + .{ "bool", .Bool }, .{ "break", .Break }, + .{ "catch", .Catch }, + .{ "const", .Const }, .{ "continue", .Continue }, .{ "default", .Default }, - .{ "const", .Const }, + .{ "do", .Do }, + .{ "else", .Else }, + .{ "enum", .Enum }, + .{ "export", .Export }, + .{ "extern", .Extern }, + .{ "false", .False }, + .{ "fib", .Fib }, + .{ "float", .Float }, + .{ "for", .For }, + .{ "foreach", .ForEach }, + .{ "from", .From }, .{ "fun", .Fun }, + .{ "Function", .Function }, + .{ "if", .If }, + .{ "import", .Import }, .{ "in", .In }, - .{ "str", .Str }, .{ "int", .Int }, - .{ "float", .Float }, - .{ "bool", .Bool }, - .{ "pat", .Pat }, - .{ "do", .Do }, - .{ "until", .Until }, .{ "is", .Is }, - .{ "object", .Object }, + .{ "namespace", .Namespace }, + .{ "null", .Null }, .{ "obj", .Obj }, - .{ "static", .Static }, + .{ "object", .Object }, + .{ "or", .Or }, + .{ "out", .Out }, + .{ "pat", .Pat }, .{ "protocol", .Protocol }, - .{ "enum", .Enum }, + .{ "resolve", .Resolve }, + .{ "resume", .Resume }, + .{ "return", .Return }, + .{ "static", .Static }, + .{ "str", .Str }, + .{ "switch", .Switch }, + .{ "test", .Test }, .{ "throw", .Throw }, - .{ "catch", .Catch }, + .{ "true", .True }, .{ "try", .Try }, - .{ "test", .Test }, - .{ "Function", .Function }, - .{ "import", .Import }, - .{ "export", .Export }, - .{ "extern", .Extern }, - .{ "from", .From }, - .{ "fib", .Fib }, - .{ "resume", .Resume }, - .{ "resolve", .Resolve }, - .{ "yield", .Yield }, - .{ "any", .Any }, - .{ "zdef", .Zdef }, .{ "type", .Type }, .{ "typeof", .TypeOf }, + .{ "ud", .Ud }, + .{ "until", .Until }, .{ "var", .Var }, - .{ "out", .Out }, + .{ "void", .Void }, + .{ "while", .While }, + .{ "yield", .Yield }, + .{ "zdef", .Zdef }, }, ); diff --git a/src/lib/buffer.buzz b/src/lib/buffer.buzz index e1707b35..4552f60a 100644 --- a/src/lib/buffer.buzz +++ b/src/lib/buffer.buzz @@ -1,4 +1,5 @@ -import "errors"; +namespace buffer; + import "ffi"; import "std"; @@ -44,21 +45,21 @@ extern fun BufferAt(ud userdata, int index) > int; || @private extern fun BufferSetAt(ud userdata, int index, int value) > void; || @private -extern fun BufferWriteZ(ud userdata, str zigType, [any] values) > void !> WriteWhileReadingError, FFITypeMismatchError; +extern fun BufferWriteZ(ud userdata, str zigType, [any] values) > void !> WriteWhileReadingError, ffi.FFITypeMismatchError; || @private -extern fun BufferWriteZAt(ud userdata, int at, str zigType, [any] values) > void !> WriteWhileReadingError, FFITypeMismatchError; +extern fun BufferWriteZAt(ud userdata, int at, str zigType, [any] values) > void !> WriteWhileReadingError, ffi.FFITypeMismatchError; || @private -extern fun BufferReadZ::(ud userdata, str zigType) > T !> FFITypeMismatchError; +extern fun BufferReadZ::(ud userdata, str zigType) > T !> ffi.FFITypeMismatchError; || @private -extern fun BufferReadZAt::(ud userdata, int at, str zigType) > T !> FFITypeMismatchError; +extern fun BufferReadZAt::(ud userdata, int at, str zigType) > T !> ffi.FFITypeMismatchError; || @private -extern fun BufferWriteStruct::(ud userdata, type structType, [T] values) > void !> WriteWhileReadingError, FFITypeMismatchError; +extern fun BufferWriteStruct::(ud userdata, type structType, [T] values) > void !> WriteWhileReadingError, ffi.FFITypeMismatchError; || @private -extern fun BufferWriteStructAt::(ud userdata, type structType, int at, [T] values) > void !> WriteWhileReadingError, FFITypeMismatchError; +extern fun BufferWriteStructAt::(ud userdata, type structType, int at, [T] values) > void !> WriteWhileReadingError, ffi.FFITypeMismatchError; || @private -extern fun BufferReadStruct::(ud userdata, type structType) > T !> FFITypeMismatchError; +extern fun BufferReadStruct::(ud userdata, type structType) > T !> ffi.FFITypeMismatchError; || @private -extern fun BufferReadStructAt::(ud userdata, type structType, int at) > T !> FFITypeMismatchError; +extern fun BufferReadStructAt::(ud userdata, type structType, int at) > T !> ffi.FFITypeMismatchError; || Read and write data to a string buffer export object Buffer { @@ -105,35 +106,35 @@ export object Buffer { BufferWrite(this.buffer, bytes: bytes); } - fun writeZ::(str zigType, [T] values) > void !> WriteWhileReadingError, FFITypeMismatchError { + fun writeZ::(str zigType, [T] values) > void !> WriteWhileReadingError, ffi.FFITypeMismatchError { BufferWriteZ(this.buffer, zigType: zigType, values: values); } - fun writeZAt::(int at, str zigType, [T] values) > void !> WriteWhileReadingError, FFITypeMismatchError { + fun writeZAt::(int at, str zigType, [T] values) > void !> WriteWhileReadingError, ffi.FFITypeMismatchError { BufferWriteZAt(this.buffer, at: at, zigType: zigType, values: values); } - fun readZ::(str zigType) > T !> FFITypeMismatchError { + fun readZ::(str zigType) > T !> ffi.FFITypeMismatchError { return BufferReadZ::(this.buffer, zigType: zigType); } - fun readZAt::(int at, str zigType) > T !> FFITypeMismatchError { + fun readZAt::(int at, str zigType) > T !> ffi.FFITypeMismatchError { return BufferReadZAt::(this.buffer, at: at, zigType: zigType); } - fun writeStruct::(type structType, [T] values) > void !> WriteWhileReadingError, FFITypeMismatchError { + fun writeStruct::(type structType, [T] values) > void !> WriteWhileReadingError, ffi.FFITypeMismatchError { BufferWriteStruct::(this.buffer, structType: structType, values: values); } - fun writeStructAt::(type structType, int at, [T] values) > void !> WriteWhileReadingError, FFITypeMismatchError { + fun writeStructAt::(type structType, int at, [T] values) > void !> WriteWhileReadingError, ffi.FFITypeMismatchError { BufferWriteStructAt::(this.buffer, structType: structType, at: at, values: values); } - fun readStruct::(type structType) > T !> FFITypeMismatchError { + fun readStruct::(type structType) > T !> ffi.FFITypeMismatchError { return BufferReadStruct::(this.buffer, structType: structType); } - fun readStructAt::(type structType, int at) > T !> FFITypeMismatchError { + fun readStructAt::(type structType, int at) > T !> ffi.FFITypeMismatchError { return BufferReadStructAt::(this.buffer, structType: structType, at: at); } diff --git a/src/lib/buzz_serialize.zig b/src/lib/buzz_serialize.zig index f0794f4e..fdd55c6e 100644 --- a/src/lib/buzz_serialize.zig +++ b/src/lib/buzz_serialize.zig @@ -9,7 +9,7 @@ pub const os = if (is_wasm) else std.os; -pub export fn serialize(ctx: *api.NativeCtx) c_int { +pub export fn serializeValue(ctx: *api.NativeCtx) c_int { const to_serialize = ctx.vm.bz_peek(0); var error_value = api.Value.Void; diff --git a/src/lib/crypto.buzz b/src/lib/crypto.buzz index b7816e9e..070c88b3 100644 --- a/src/lib/crypto.buzz +++ b/src/lib/crypto.buzz @@ -1,3 +1,5 @@ +namespace crypto; + || Hash algorithms export enum HashAlgorithm { Md5, diff --git a/src/lib/debug.buzz b/src/lib/debug.buzz index a23bc72e..1dcaf2c0 100644 --- a/src/lib/debug.buzz +++ b/src/lib/debug.buzz @@ -1,5 +1,4 @@ -import "std"; -import "errors"; +namespace debug; || Dump any value to stdout export extern fun dump(any value) > void; diff --git a/src/lib/errors.buzz b/src/lib/errors.buzz index b31e4431..c54fd587 100644 --- a/src/lib/errors.buzz +++ b/src/lib/errors.buzz @@ -1,3 +1,5 @@ +namespace errors; + export enum FileSystemError { AccessDenied, AntivirusInterference, diff --git a/src/lib/ffi.buzz b/src/lib/ffi.buzz index 0bba175c..d03f3737 100644 --- a/src/lib/ffi.buzz +++ b/src/lib/ffi.buzz @@ -1,3 +1,5 @@ +namespace ffi; + export fun cstr(str string) -> "{string}\0"; export object FFITypeMismatchError { diff --git a/src/lib/fs.buzz b/src/lib/fs.buzz index 729e40bb..06295db4 100644 --- a/src/lib/fs.buzz +++ b/src/lib/fs.buzz @@ -1,15 +1,15 @@ -import "os" as os; +namespace fs; + +import "os"; import "errors"; || Returns current directory absolute path || @return current directory -export fun currentDirectory() > str !> FileSystemError, InvalidArgumentError { - str? dir = os.env("PWD"); - - if (dir != null) { - return dir!; +export fun currentDirectory() > str !> errors.FileSystemError, errors.InvalidArgumentError { + if (os.env("PWD") -> dir) { + return dir; } else { - throw FileSystemError.BadPathName; + throw errors.FileSystemError.BadPathName; } | TODO: should not be required since there's throw in the else branch @@ -18,22 +18,22 @@ export fun currentDirectory() > str !> FileSystemError, InvalidArgumentError { || Creates directory path || @param path directory to create -export extern fun makeDirectory(str path) > void !> FileSystemError, UnexpectedError; +export extern fun makeDirectory(str path) > void !> errors.FileSystemError, errors.UnexpectedError; || Deletes directory or file at path || @param path direcotry/file to delete -export extern fun delete(str path) > void !> FileSystemError, UnexpectedError; +export extern fun delete(str path) > void !> errors.FileSystemError, errors.UnexpectedError; || Moves/renames file || @param source file to move || @param destination where to move it -export extern fun move(str source, str destination) > void !> FileSystemError, UnexpectedError; +export extern fun move(str source, str destination) > void !> errors.FileSystemError, errors.UnexpectedError; || List files under path || @param path directory to list -export extern fun list(str path) > [str] !> FileSystemError, UnexpectedError; +export extern fun list(str path) > [str] !> errors.FileSystemError, errors.UnexpectedError; || Returns true if path exists || @param path directory/file to test || @return wether file exists -export extern fun exists(str path) > bool !> FileSystemError; \ No newline at end of file +export extern fun exists(str path) > bool !> errors.FileSystemError; \ No newline at end of file diff --git a/src/lib/gc.buzz b/src/lib/gc.buzz index 1bcd59f2..8fa58478 100644 --- a/src/lib/gc.buzz +++ b/src/lib/gc.buzz @@ -1,3 +1,5 @@ +namespace gc; + || Error occured while collecting object CollectError {} diff --git a/src/lib/http.buzz b/src/lib/http.buzz index 84fedf20..99c4c8df 100644 --- a/src/lib/http.buzz +++ b/src/lib/http.buzz @@ -1,7 +1,7 @@ +namespace http; + import "std"; -import "os"; import "buffer"; -import "io"; import "errors"; export enum HttpError { @@ -165,7 +165,7 @@ export object Client { }; } - fun send(Request request) > Response *> void !> HttpError, InvalidArgumentError, HttpParseError { + fun send(Request request) > Response *> void !> HttpError, errors.InvalidArgumentError, HttpParseError { _ = this.start(request); yield void; @@ -202,9 +202,9 @@ export object Request { str? body = null, bool collected = false, - fun wait() > Response !> HttpError, InvalidArgumentError, HttpParseError { + fun wait() > Response !> HttpError, errors.InvalidArgumentError, HttpParseError { if (this.response != null) { - throw InvalidArgumentError{}; + throw errors.InvalidArgumentError{}; } if (this.request -> request) { @@ -213,12 +213,12 @@ export object Request { return HttpRequestRead(request); } - throw InvalidArgumentError{}; + throw errors.InvalidArgumentError{}; } fun toString() > str { try { - var result = Buffer.init(); + var result = buffer.Buffer.init(); result.write("{this.method.value} {this.uri} HTTP/1.1\r\n"); foreach (str key, str value in this.headers) { @@ -253,7 +253,7 @@ export object Response { fun toString() > str { try { - var result = Buffer.init(); + var result = buffer.Buffer.init(); result.write("HTTP/1.1 {this.status} {reasons[this.status]}\r\n"); foreach (str key, str value in this.headers) { diff --git a/src/lib/io.buzz b/src/lib/io.buzz index 8c33cbed..135de88e 100644 --- a/src/lib/io.buzz +++ b/src/lib/io.buzz @@ -1,17 +1,19 @@ +namespace io; + import "errors"; || @private -extern fun FileOpen(str filename, int mode) > int !> FileSystemError, UnexpectedError; +extern fun FileOpen(str filename, int mode) > int !> errors.FileSystemError, errors.UnexpectedError; || @private extern fun FileClose(int fd) > void; || @private -extern fun FileReadAll(int fd, int? maxSize) > str !> ReadWriteError, FileSystemError, UnexpectedError; +extern fun FileReadAll(int fd, int? maxSize) > str !> errors.ReadWriteError, errors.FileSystemError, errors.UnexpectedError; || @private -extern fun FileReadLine(int fd, int? maxSize) > str? !> ReadWriteError, FileSystemError, UnexpectedError; +extern fun FileReadLine(int fd, int? maxSize) > str? !> errors.ReadWriteError, errors.FileSystemError, errors.UnexpectedError; || @private -extern fun FileRead(int fd, int n) > str? !> ReadWriteError, FileSystemError, InvalidArgumentError, UnexpectedError; +extern fun FileRead(int fd, int n) > str? !> errors.ReadWriteError, errors.FileSystemError, errors.InvalidArgumentError, errors.UnexpectedError; || @private -extern fun FileWrite(int fd, str bytes) > void !> FileSystemError, ReadWriteError, UnexpectedError; +extern fun FileWrite(int fd, str bytes) > void !> errors.FileSystemError, errors.ReadWriteError, errors.UnexpectedError; || @private extern fun getStdIn() > int; || @private @@ -37,7 +39,7 @@ export object File { || @param filename Path of file to open || @param mode Mode with which to open it || @return opened file - static fun open(str filename, FileMode mode) > File !> FileSystemError, UnexpectedError { + static fun open(str filename, FileMode mode) > File !> errors.FileSystemError, errors.UnexpectedError { return File { fd = FileOpen(filename, mode: mode.value), }; @@ -54,26 +56,26 @@ export object File { || Reads file until `EOF` || @return Read data - fun readAll(int? maxSize) > str !> ReadWriteError, FileSystemError, UnexpectedError { + fun readAll(int? maxSize) > str !> errors.ReadWriteError, errors.FileSystemError, errors.UnexpectedError { return FileReadAll(this.fd, maxSize); } || Reads next line, returns null if nothing to read || @return Read data - fun readLine(int? maxSize) > str? !> ReadWriteError, FileSystemError, UnexpectedError { + fun readLine(int? maxSize) > str? !> errors.ReadWriteError, errors.FileSystemError, errors.UnexpectedError { return FileReadLine(this.fd, maxSize); } || Reads `n` bytes, returns null if nothing to read || @param n how many bytes to read || @return Read data - fun read(int n) > str? !> ReadWriteError, FileSystemError, InvalidArgumentError, UnexpectedError { + fun read(int n) > str? !> errors.ReadWriteError, errors.FileSystemError, errors.InvalidArgumentError, errors.UnexpectedError { return FileRead(this.fd, n: n); } || Write bytes || @param bytes string to write - fun write(str bytes) > void !> FileSystemError, ReadWriteError, UnexpectedError { + fun write(str bytes) > void !> errors.FileSystemError, errors.ReadWriteError, errors.UnexpectedError { FileWrite(this.fd, bytes: bytes); } @@ -92,4 +94,4 @@ export const File stderr = File{ fd = getStdErr() }; || Run a buzz file || @param filename path to buzz file -export extern fun runFile(str filename) > void !> CompileError, InterpretError, FileSystemError, ReadWriteError; \ No newline at end of file +export extern fun runFile(str filename) > void !> errors.CompileError, errors.InterpretError, errors.FileSystemError, errors.ReadWriteError; \ No newline at end of file diff --git a/src/lib/math.buzz b/src/lib/math.buzz index 615c3550..e4ba2370 100644 --- a/src/lib/math.buzz +++ b/src/lib/math.buzz @@ -1,3 +1,5 @@ +namespace math; + import "errors"; || @return absolute value of n @@ -62,7 +64,7 @@ extern fun bzsqrt(float n) > float; extern fun bztan(float n) > float; || @return `x`^`y` -extern fun pow(float x, float y) > float !> OverflowError, UnderflowError; +extern fun pow(float x, float y) > float !> errors.OverflowError, errors.UnderflowError; export abs; export acos; diff --git a/src/lib/os.buzz b/src/lib/os.buzz index 1b35a348..ee01fea1 100644 --- a/src/lib/os.buzz +++ b/src/lib/os.buzz @@ -1,3 +1,5 @@ +namespace os; + import "errors"; || Sleep for the given amount of ms @@ -26,24 +28,24 @@ export buzzExit as exit; || Execute command and return its exit code || @param command command to execute || @return exit code of the command -export extern fun execute([str] command) > int !> FileSystemError, UnexpectedError; +export extern fun execute([str] command) > int !> errors.FileSystemError, errors.UnexpectedError; || @private -extern fun SocketConnect(str address, int port, int netProtocol) > int !> InvalidArgumentError, SocketError, NotYetImplementedError; +extern fun SocketConnect(str address, int port, int netProtocol) > int !> errors.InvalidArgumentError, errors.SocketError, errors.NotYetImplementedError; || @private extern fun SocketClose(int fd) > void; || @private -extern fun SocketRead(int fd, int n) > str? !> InvalidArgumentError, FileSystemError, ReadWriteError, UnexpectedError; +extern fun SocketRead(int fd, int n) > str? !> errors.InvalidArgumentError, errors.FileSystemError, errors.ReadWriteError, errors.UnexpectedError; || @private -extern fun SocketWrite(int fd, str bytes) > void !> FileSystemError, ReadWriteError, UnexpectedError; +extern fun SocketWrite(int fd, str bytes) > void !> errors.FileSystemError, errors.ReadWriteError, errors.UnexpectedError; || @private -extern fun SocketServerStart(str address, int port, bool reuseAddr, bool reusePort) > int !> InvalidArgumentError, SocketError, UnexpectedError, FileSystemError; +extern fun SocketServerStart(str address, int port, bool reuseAddr, bool reusePort) > int !> errors.InvalidArgumentError, errors.SocketError, errors.UnexpectedError, errors.FileSystemError; || @private -extern fun SocketServerAccept(int fd) > int !> SocketError, UnexpectedError; +extern fun SocketServerAccept(int fd) > int !> errors.SocketError, errors.UnexpectedError; || @private -extern fun SocketReadLine(int fd, int? maxSize) > str? !> FileSystemError, UnexpectedError, ReadWriteError; +extern fun SocketReadLine(int fd, int? maxSize) > str? !> errors.FileSystemError, errors.UnexpectedError, errors.ReadWriteError; || @private -extern fun SocketReadAll(int fd, int? maxSize) > str? !> FileSystemError, UnexpectedError, ReadWriteError; +extern fun SocketReadAll(int fd, int? maxSize) > str? !> errors.FileSystemError, errors.UnexpectedError, errors.ReadWriteError; || Protocols supported over a socket export enum SocketProtocol { @@ -62,7 +64,7 @@ export object Socket { || @param port Port to which to connect || @param protocol Protocol to use || @return A new `Socket` opened and ready to use - static fun connect(str address, int port = 0, SocketProtocol netProtocol) > Socket !> InvalidArgumentError, SocketError, NotYetImplementedError { + static fun connect(str address, int port = 0, SocketProtocol netProtocol) > Socket !> errors.InvalidArgumentError, errors.SocketError, errors.NotYetImplementedError { return Socket{ fd = SocketConnect(address, port: port, netProtocol: netProtocol.value), }; @@ -76,25 +78,25 @@ export object Socket { || Receive at most `n` bytes from the socket || @param n How many bytes we're prepare to receive || @return The bytes received or null if nothing to read - fun receive(int n) > str? !> InvalidArgumentError, FileSystemError, ReadWriteError, UnexpectedError { + fun receive(int n) > str? !> errors.InvalidArgumentError, errors.FileSystemError, errors.ReadWriteError, errors.UnexpectedError { return SocketRead(this.fd, n: n); } || Receive from socket until it's closed or a linefeed is received || @return The bytes received or null if nothing to read - fun receiveLine(int? maxSize) > str? !> FileSystemError, UnexpectedError, ReadWriteError { + fun receiveLine(int? maxSize) > str? !> errors.FileSystemError, errors.UnexpectedError, errors.ReadWriteError { return SocketReadLine(this.fd, maxSize); } || Receive from socket until it's closed || @return The bytes received or null if nothing to read - fun receiveAll(int? maxSize) > str? !> FileSystemError, UnexpectedError, ReadWriteError { + fun receiveAll(int? maxSize) > str? !> errors.FileSystemError, errors.UnexpectedError, errors.ReadWriteError { return SocketReadAll(this.fd, maxSize); } || Send bytes on the socket || @param bytes Bytes to send - fun send(str bytes) > void !> FileSystemError, ReadWriteError, UnexpectedError { + fun send(str bytes) > void !> errors.FileSystemError, errors.ReadWriteError, errors.UnexpectedError { SocketWrite(this.fd, bytes: bytes); } } @@ -114,7 +116,7 @@ export object TcpServer { || @param reuseAddr Wether we want to accept multiple connections || @param reusePort Wether we want to accept multiple connections || @return New `TcpServer` bound to `
:` - static fun init(str address, int port, bool reuseAddr, bool reusePort) > TcpServer !> SocketError, UnexpectedError, InvalidArgumentError, FileSystemError { + static fun init(str address, int port, bool reuseAddr, bool reusePort) > TcpServer !> errors.SocketError, errors.UnexpectedError, errors.InvalidArgumentError, errors.FileSystemError { return TcpServer{ serverSocket = Socket{ fd = SocketServerStart(address, port: port, reuseAddr: reuseAddr, reusePort: reusePort), @@ -126,7 +128,7 @@ export object TcpServer { || Accept a new connection || @return Socket opened with the client - fun accept() > Socket !> SocketError, UnexpectedError { + fun accept() > Socket !> errors.SocketError, errors.UnexpectedError { return Socket{ fd = SocketServerAccept(this.serverSocket.fd), }; diff --git a/src/lib/serialize.buzz b/src/lib/serialize.buzz index 583a5690..f38471c3 100644 --- a/src/lib/serialize.buzz +++ b/src/lib/serialize.buzz @@ -1,5 +1,7 @@ -import "std"; +namespace serialize; + import "buffer"; +import "std"; || Utility object to manage deserialized data from, for example, decoded JSON export object Boxed { @@ -7,7 +9,7 @@ export object Boxed { static fun init(any data) > Boxed !> CircularReference, NotSerializable { return Boxed{ - data = serialize(data), + data = serializeValue(data), }; } @@ -100,7 +102,7 @@ export object NotSerializable { str message = "Not serializable", } -export extern fun serialize(any value) > any !> CircularReference, NotSerializable; +export extern fun serializeValue(any value) > any !> CircularReference, NotSerializable; export object JsonParseError { str? message = null, @@ -162,7 +164,7 @@ object JsonParser { } } - fun next() > any !> JsonParseError, WriteWhileReadingError { + fun next() > any !> JsonParseError, buffer.WriteWhileReadingError { this.skipWhitespaces(); if (this.offset >= this.source.len()) { @@ -193,7 +195,7 @@ object JsonParser { throw JsonParseError{ message = "Could not parse JSON: unexpected character `{char}` at offset {this.offset}" }; } - fun array() > [any] !> JsonParseError, WriteWhileReadingError { + fun array() > [any] !> JsonParseError, buffer.WriteWhileReadingError { [any] array = []; while (true) { @@ -217,7 +219,7 @@ object JsonParser { return array; } - fun map() > {str: any} !> JsonParseError, WriteWhileReadingError { + fun map() > {str: any} !> JsonParseError, buffer.WriteWhileReadingError { {str: any} map = {}; while (true) { @@ -254,7 +256,7 @@ object JsonParser { str number = parsed; bool isFloat = false; - while (parseInt(this.peek() ?? "NaN") != null or this.peek() == ".") { + while (std.parseInt(this.peek() ?? "NaN") != null or this.peek() == ".") { str? char = this.advance(); if (char == null) { @@ -269,19 +271,19 @@ object JsonParser { } if (isFloat) { - if (parseFloat(number) -> floating) { + if (std.parseFloat(number) -> floating) { return floating; } - } else if (parseInt(number) -> integer) { + } else if (std.parseInt(number) -> integer) { return integer; } throw JsonParseError{ message = "Could not parse JSON: `{number}` is not a number" }; } - fun string() > str !> WriteWhileReadingError { + fun string() > str !> buffer.WriteWhileReadingError { str? char = this.advance(); - Buffer string = Buffer.init(); + var string = buffer.Buffer.init(); while (char != null and char != "\"") { if (char == "\\") { @@ -355,7 +357,7 @@ export fun jsonEncode(Boxed data) > str !> CircularReference, NotSerializable { || Decode string into a Json instance || @param str json The JSON string || @return Boxed -export fun jsonDecode(str json) > Boxed !> JsonParseError, WriteWhileReadingError { +export fun jsonDecode(str json) > Boxed !> JsonParseError, buffer.WriteWhileReadingError { return Boxed{ data = JsonParser{ source = json diff --git a/src/lib/std.buzz b/src/lib/std.buzz index e74edb3d..bb2e6f1c 100644 --- a/src/lib/std.buzz +++ b/src/lib/std.buzz @@ -1,3 +1,5 @@ +namespace std; + || If condition is false print message and exit program || @param condition assert condition || @param message message printed if `condition` is false diff --git a/src/lib/test.buzz b/src/lib/testing.buzz similarity index 93% rename from src/lib/test.buzz rename to src/lib/testing.buzz index 66bbed5f..bd0437d3 100644 --- a/src/lib/test.buzz +++ b/src/lib/testing.buzz @@ -1,4 +1,5 @@ -import "std"; +namespace testing; + import "os"; import "io"; @@ -120,9 +121,9 @@ export object Tester { } fun it(str message, Function() > void fn) > void { - float startTime = time(); + float startTime = os.time(); - stdout.write(yellow("▶ Test: {message}\n")) catch void; + io.stdout.write(yellow("▶ Test: {message}\n")) catch void; if (this.beforeEach -> beforeEach) { beforeEach(this); @@ -137,7 +138,7 @@ export object Tester { this.tests.append(previousFailCount == this.failedAsserts()); - this.elapsed = this.elapsed + (time() - startTime); + this.elapsed = this.elapsed + (os.time() - startTime); } fun summary() > void { @@ -147,17 +148,17 @@ export object Tester { const failed = this.failedTests(); - stdout.write("\n") catch void; + io.stdout.write("\n") catch void; foreach (bool testStatus in this.tests) { if (testStatus) { - stdout.write(green("●")) catch void; + io.stdout.write(green("●")) catch void; } else { - stdout.write(yellow("●")) catch void; + io.stdout.write(yellow("●")) catch void; } } - stdout.write( + io.stdout.write( green("\n{this.succeededTests()}") + dim(" successes, ") + yellow("{failed}") @@ -167,12 +168,12 @@ export object Tester { ) catch void; if (failed > 0) { - exit(1); + os.exit(1); } } fun report(str? error, str? message) > void { - stderr.write(red(" Assert failed: {message ?? ""}") + dim("\n {error}\n")) catch void; + io.stderr.write(red(" Assert failed: {message ?? ""}") + dim("\n {error}\n")) catch void; } fun assert(bool condition, str? error, str? message) > void { diff --git a/src/scanner.zig b/src/scanner.zig index bcc16337..1e13eaff 100644 --- a/src/scanner.zig +++ b/src/scanner.zig @@ -669,6 +669,7 @@ pub const Scanner = struct { .Question, .AsQuestion, .Out, + .Namespace, => if (true_color) Color.keyword else Color.magenta, // Punctuation .LeftBracket, diff --git a/tests/001-basic-types.buzz b/tests/001-basic-types.buzz index c4c6cb2f..a5c01ca7 100644 --- a/tests/001-basic-types.buzz +++ b/tests/001-basic-types.buzz @@ -10,31 +10,31 @@ test "Basic types" { test "Underscore on number literals" { int a = 100_000; - assert(a == 100000, message: "Could use an underscore on an int"); + std.assert(a == 100000, message: "Could use an underscore on an int"); float b = 3.1_4; - assert(b == 3.14, message: "Could use an underscore on a float"); + std.assert(b == 3.14, message: "Could use an underscore on a float"); int bin = 0b1_0001; - assert(bin == 17, message: "Clould use an underscore on a binary int"); + std.assert(bin == 17, message: "Clould use an underscore on a binary int"); int h = 0xF_FFF; - assert(h == 65535, message: "Clould use an underscore on a hex int"); + std.assert(h == 65535, message: "Clould use an underscore on a hex int"); } test "Char literal" { int char = 'A'; - assert(char == 65, message: "Could use char literal"); + std.assert(char == 65, message: "Could use char literal"); int quote = '\''; - assert(quote == 39, message: "Could escape ' in char literal"); + std.assert(quote == 39, message: "Could escape ' in char literal"); int slash = '\\'; - assert(slash == 92, message: "Could escape \\ in char literal"); + std.assert(slash == 92, message: "Could escape \\ in char literal"); } diff --git a/tests/002-operators.buzz b/tests/002-operators.buzz index a6d1ae85..9d1ba565 100644 --- a/tests/002-operators.buzz +++ b/tests/002-operators.buzz @@ -1,30 +1,30 @@ import "std"; test "Binary operators" { - assert(12 == 12, message: "equality (number)"); - assert(12 + 12 == 24, message: "addition"); - assert(12 - 12 == 0, message: "substraction"); - assert(12 * 12 == 144, message: "multiplication"); - assert(12 / 12 == 1, message: "division"); - assert(12 % 12 == 0, message: "modulo"); - assert(12 != 13, message: "inequality"); - assert(12 >= 12, message: "greater or equal"); - assert(12 <= 12, message: "less or equal"); - assert(12 > 11, message: "greater"); - assert(12 < 13, message: "less"); - assert(12 > 3 and 5 < 12, message: "and"); - assert(12 > 3 or 12 < 5, message: "or"); + std.assert(12 == 12, message: "equality (number)"); + std.assert(12 + 12 == 24, message: "addition"); + std.assert(12 - 12 == 0, message: "substraction"); + std.assert(12 * 12 == 144, message: "multiplication"); + std.assert(12 / 12 == 1, message: "division"); + std.assert(12 % 12 == 0, message: "modulo"); + std.assert(12 != 13, message: "inequality"); + std.assert(12 >= 12, message: "greater or equal"); + std.assert(12 <= 12, message: "less or equal"); + std.assert(12 > 11, message: "greater"); + std.assert(12 < 13, message: "less"); + std.assert(12 > 3 and 5 < 12, message: "and"); + std.assert(12 > 3 or 12 < 5, message: "or"); } test "Binary operators for strings" { - assert("hello " + "world" == "hello world", message: "string concat"); - assert("hello" == "hello", message: "equality (string"); + std.assert("hello " + "world" == "hello world", message: "string concat"); + std.assert("hello" == "hello", message: "equality (string"); } test "Unary operators (constant folded)" { - assert(-12 < 0, message: "negate operator"); - assert(!false, message: "not operator"); - assert(~15 == -16, message: "~"); + std.assert(-12 < 0, message: "negate operator"); + std.assert(!false, message: "not operator"); + std.assert(~15 == -16, message: "~"); } test "Unary operators" { @@ -32,7 +32,7 @@ test "Unary operators" { bool b = false; int c = 15; - assert(-a < 0, message: "negate operator"); - assert(!b, message: "not operator"); - assert(~c == -16, message: "~"); + std.assert(-a < 0, message: "negate operator"); + std.assert(!b, message: "not operator"); + std.assert(~c == -16, message: "~"); } \ No newline at end of file diff --git a/tests/003-control-flow.buzz b/tests/003-control-flow.buzz index 1419c8d5..c067e2f7 100644 --- a/tests/003-control-flow.buzz +++ b/tests/003-control-flow.buzz @@ -2,29 +2,29 @@ import "std"; test "if statement" { if (2 > 1) { - assert(true, message: "if"); + std.assert(true, message: "if"); } else { - assert(false, message: "else"); + std.assert(false, message: "else"); } if (2 < 1) { - assert(false, message: "if"); + std.assert(false, message: "if"); } else { - assert(true, message: "else"); + std.assert(true, message: "else"); } } test "if statement with placeholder" { if (ahead == "wat") { - assert(true, message: "works with a placeholder"); + std.assert(true, message: "works with a placeholder"); } else { - assert(false, message: "if failed with placeholder"); + std.assert(false, message: "if failed with placeholder"); } | if (objAhead.name == "joe") { - | assert(true, message: "works with a placeholder"); + | std.assert(true, message: "works with a placeholder"); | } else { - | assert(false, message: "if failed with placeholder"); + | std.assert(false, message: "if failed with placeholder"); | } } @@ -34,7 +34,7 @@ test "while statement" { i = i + 1; } - assert(i == 10, message: "while"); + std.assert(i == 10, message: "while"); } | test "while statement with placeholder" { @@ -42,7 +42,7 @@ test "while statement" { | objAhead.age = objAhead.age + 1; | } -| assert(objAhead.age == 10, message: "while with placeholder"); +| std.assert(objAhead.age == 10, message: "while with placeholder"); | } test "do-until statement" { @@ -51,7 +51,7 @@ test "do-until statement" { i = i - 1; } until (i == 0) - assert(i == 0, message: "do until"); + std.assert(i == 0, message: "do until"); } str ahead = "wat"; diff --git a/tests/004-lists.buzz b/tests/004-lists.buzz index b744675d..71118571 100644 --- a/tests/004-lists.buzz +++ b/tests/004-lists.buzz @@ -3,10 +3,10 @@ import "std"; test "Lists" { [int] list = [1, 2, 3, 4]; - assert(list.len() == 4, message: "len"); + std.assert(list.len() == 4, message: "len"); [str] strList = ["hello", "world"]; - assert(strList[0] == "hello", message: "subscript"); + std.assert(strList[0] == "hello", message: "subscript"); | A lone list expression _ = ["hello", "world"]; @@ -14,57 +14,57 @@ test "Lists" { [[str]] nestedList = [["hello"], ["world"]]; - assert(nestedList[0][0] == "hello", message: "nested list"); + std.assert(nestedList[0][0] == "hello", message: "nested list"); strList[1] = "yolo"; - assert(strList[1] == "yolo", message: "list assignment"); + std.assert(strList[1] == "yolo", message: "list assignment"); strList.append("dojo"); - assert(strList[strList.len() - 1] == "dojo", message: "append to list"); + std.assert(strList[strList.len() - 1] == "dojo", message: "append to list"); str? removed = strList.remove(1); - assert(strList.len() == 2, message: "removed element form list"); - assert(strList[0] == "hello" and strList[1] == "dojo", message: "item were properly shifted"); - assert(removed == "yolo", message: "removed element has the correct value"); + std.assert(strList.len() == 2, message: "removed element form list"); + std.assert(strList[0] == "hello" and strList[1] == "dojo", message: "item were properly shifted"); + std.assert(removed == "yolo", message: "removed element has the correct value"); - assert(strList.remove(12) == null, message: "returns null when removing non existent index"); + std.assert(strList.remove(12) == null, message: "returns null when removing non existent index"); } test "list.sub" { [int] list = [1, 2, 3, 4]; [int] sub = list.sub(1, len: 2); - assert(sub.len() == 2 and sub[0] == 2 and sub[1] == 3, message: "list.sub"); + std.assert(sub.len() == 2 and sub[0] == 2 and sub[1] == 3, message: "list.sub"); } test "list.indexOf" { - assert([0, 1, 2, 3].indexOf(2) == 2, message: "list.indexOf"); + std.assert([0, 1, 2, 3].indexOf(2) == 2, message: "list.indexOf"); } test "list.join" { - assert([1, 2, 3, 4].join(",") == "1,2,3,4", message: "list.join"); + std.assert([1, 2, 3, 4].join(",") == "1,2,3,4", message: "list.join"); } test "list concat" { - assert(([1, 2, 3] + [4, 5, 6]).join(",") == "1,2,3,4,5,6", message: "list concat"); + std.assert(([1, 2, 3] + [4, 5, 6]).join(",") == "1,2,3,4,5,6", message: "list concat"); } test "list.clone" { [int] list = [1, 2, 3]; [int] copy = list.clone(); - assert(list.len() == copy.len(), message: "Could clone list"); + std.assert(list.len() == copy.len(), message: "Could clone list"); foreach (int i, int el in copy) { - assert(list[i] == el, message: "Could clone list"); + std.assert(list[i] == el, message: "Could clone list"); } } test "empty list type inferring" { var list = []; - assert(typeof list == <[any]>); + std.assert(typeof list == <[any]>); [str] slist = []; - assert(typeof slist == <[str]>); + std.assert(typeof slist == <[str]>); } \ No newline at end of file diff --git a/tests/005-maps.buzz b/tests/005-maps.buzz index f6a2058a..232f66fb 100644 --- a/tests/005-maps.buzz +++ b/tests/005-maps.buzz @@ -8,31 +8,31 @@ test "Maps" { _ = {1: true, 2: false}; - assert(map["bye"] is int?, message: "yeah"); + std.assert(map["bye"] is int?, message: "yeah"); - assert(map["bye"] == 2, message: "map subscript"); - assert(({1: true, 2: false})[2] == false, message: "map expression subscript"); + std.assert(map["bye"] == 2, message: "map subscript"); + std.assert(({1: true, 2: false})[2] == false, message: "map expression subscript"); - assert(map.remove("hello") == 1, message: "removed element"); - | assert(map["hello"] == null, message: "removed element"); - assert(map.size() == 1, message: "map size"); + std.assert(map.remove("hello") == 1, message: "removed element"); + | std.assert(map["hello"] == null, message: "removed element"); + std.assert(map.size() == 1, message: "map size"); } test "map merge" { {str: int} map = {"one": 1, "two": 22} + {"three": 3, "two": 2}; - assert(map["two"] == 2, message: "map merge"); - assert(map.size() == 3, message: "map merge"); + std.assert(map["two"] == 2, message: "map merge"); + std.assert(map.size() == 3, message: "map merge"); } test "map.keys" { - assert({"one": 1, "two": 2, "three": 3}.keys().join(",") == "one,two,three", message: "map.keys"); + std.assert({"one": 1, "two": 2, "three": 3}.keys().join(",") == "one,two,three", message: "map.keys"); } test "map.values" { - assert({"one": 1, "two": 2, "three": 3}.values().join(",") == "1,2,3", message: "map.values"); + std.assert({"one": 1, "two": 2, "three": 3}.values().join(",") == "1,2,3", message: "map.values"); - assert({}.keys().len() == 0, message: "yo empty map"); + std.assert({}.keys().len() == 0, message: "yo empty map"); } test "map.diff" { @@ -50,7 +50,7 @@ test "map.diff" { {str: int} diff = first.diff(second); - assert(diff.size() == 1 and diff["one"] != null, message: "Could use map.diff"); + std.assert(diff.size() == 1 and diff["one"] != null, message: "Could use map.diff"); } test "map.intersect" { @@ -68,7 +68,7 @@ test "map.intersect" { {str: int} intersect = first.intersect(second); - assert(intersect.size() == 1 and intersect["two"] != null, message: "Could use map.intersect"); + std.assert(intersect.size() == 1 and intersect["two"] != null, message: "Could use map.intersect"); } test "map.clone" { @@ -79,18 +79,18 @@ test "map.clone" { }; {str: int} copy = first.clone(); - assert(copy.size() == first.size(), message: "Could clone map"); + std.assert(copy.size() == first.size(), message: "Could clone map"); foreach (str key, int value in copy) { - assert(first[key] == value, message: "Could clone map"); + std.assert(first[key] == value, message: "Could clone map"); } } test "empty map type inferring" { var map = {}; - assert(typeof map == <{any: any}>); + std.assert(typeof map == <{any: any}>); {str: int} smap = {}; - assert(typeof smap == <{str: int}>); + std.assert(typeof smap == <{str: int}>); } \ No newline at end of file diff --git a/tests/006-enums.buzz b/tests/006-enums.buzz index 5dce28c4..d9081d0f 100644 --- a/tests/006-enums.buzz +++ b/tests/006-enums.buzz @@ -28,23 +28,23 @@ object Natural { } test "Enums" { - assert(StrEnum.one.value == "one", message: "str enum"); + std.assert(StrEnum.one.value == "one", message: "str enum"); - assert(IntEnum.one.value == 1, message: "int enum"); + std.assert(IntEnum.one.value == 1, message: "int enum"); - assert(NaturalEnum.zero.value == 0, message: "natural enum"); + std.assert(NaturalEnum.zero.value == 0, message: "natural enum"); NaturalEnum myCase = NaturalEnum.two; - assert(myCase.value == 2, message: "enum instance"); + std.assert(myCase.value == 2, message: "enum instance"); NaturalEnum? fromValue = NaturalEnum(0); - assert(fromValue != null, message: "Could get enum instance from value"); - assert(fromValue?.value == 0, message: "Could get correct enum instance from value"); + std.assert(fromValue != null, message: "Could get enum instance from value"); + std.assert(fromValue?.value == 0, message: "Could get correct enum instance from value"); } test "Enum case as default value" { - assert(getValue() == 0, message: "Could use enum case as function argument default value"); + std.assert(getValue() == 0, message: "Could use enum case as function argument default value"); - assert(Natural{}.natural == NaturalEnum.zero, message: "Could use enum case as object field default value"); + std.assert(Natural{}.natural == NaturalEnum.zero, message: "Could use enum case as object field default value"); } \ No newline at end of file diff --git a/tests/007-objects.buzz b/tests/007-objects.buzz index 38ec6703..f28f40b1 100644 --- a/tests/007-objects.buzz +++ b/tests/007-objects.buzz @@ -5,8 +5,8 @@ object First { int age = 10, fun sayHello() > void { - print("hello"); - print(this.name); + std.print("hello"); + std.print(this.name); } } @@ -15,10 +15,10 @@ test "Objects" { name = "John", }; - assert(first.name == "John", message: "object instance, field access"); + std.assert(first.name == "John", message: "object instance, field access"); first.age = 21; - assert(first.age == 21, message: "field assignment"); + std.assert(first.age == 21, message: "field assignment"); first.sayHello(); } @@ -40,5 +40,5 @@ object Second { test "Object with static fields" { Second second = Second.init(); - assert(second.id == Second.nextId, message: "could use static fields"); + std.assert(second.id == Second.nextId, message: "could use static fields"); } \ No newline at end of file diff --git a/tests/008-inline-catch.buzz b/tests/008-inline-catch.buzz index 2f0fda1f..04cd3406 100644 --- a/tests/008-inline-catch.buzz +++ b/tests/008-inline-catch.buzz @@ -10,7 +10,7 @@ fun willFailVoid() > void !> str { } test "Inline catch clauses" { - assert((willFail() catch 0) == 0, message: "error or default value"); + std.assert((willFail() catch 0) == 0, message: "error or default value"); } test "Inline catch void" { diff --git a/tests/009-gc.buzz b/tests/009-gc.buzz index 35b340e3..2dfe110f 100644 --- a/tests/009-gc.buzz +++ b/tests/009-gc.buzz @@ -25,6 +25,6 @@ test "GC, collecting unreferenced objects" { gc.collect(); - assert(gc.allocated() <= before, message: "Garbage was collected"); - assert(collectorCalled, message: "Object collector was called"); + std.assert(gc.allocated() <= before, message: "Garbage was collected"); + std.assert(collectorCalled, message: "Object collector was called"); } \ No newline at end of file diff --git a/tests/010-placeholder-cycle.buzz b/tests/010-placeholder-cycle.buzz index 7c0ac628..8374d15d 100644 --- a/tests/010-placeholder-cycle.buzz +++ b/tests/010-placeholder-cycle.buzz @@ -21,6 +21,6 @@ object Node { } test "Cyclic placeholders" { - print("{A}"); - print("{B}"); + std.print("{A}"); + std.print("{B}"); } \ No newline at end of file diff --git a/tests/011-list-map-properties.buzz b/tests/011-list-map-properties.buzz index 8fcd372e..f8d7c479 100644 --- a/tests/011-list-map-properties.buzz +++ b/tests/011-list-map-properties.buzz @@ -14,6 +14,6 @@ test "List and Map as Object properties" { }, }; - assert(hey.ages[0] == 1, message: "list access"); - assert(hey.names[1] == "hello", message: "map access"); + std.assert(hey.ages[0] == 1, message: "list access"); + std.assert(hey.names[1] == "hello", message: "map access"); } \ No newline at end of file diff --git a/tests/012-lambda.buzz b/tests/012-lambda.buzz index f8ca0e76..3db08b71 100644 --- a/tests/012-lambda.buzz +++ b/tests/012-lambda.buzz @@ -3,7 +3,7 @@ import "std"; test "Lambda/Anonymous functions" { Function(int n) > int mul = fun (int n) > int -> n * 2; - assert(mul(1) == 2, message: "called a lambda function"); + std.assert(mul(1) == 2, message: "called a lambda function"); } fun callThis(Function(int n) > int fn, int arg) > int { @@ -11,13 +11,13 @@ fun callThis(Function(int n) > int fn, int arg) > int { } test "Function as arguments" { - assert((fun (int n) > int { return n * n; })(10) == 100, message: "called anonymous function"); - assert((fun (int n) > int -> n * n)(10) == 100, message: "called lambda function"); - assert(callThis(fun (int n) > int -> n * 2, arg: 2) == 4, message: "called a function from a function"); + std.assert((fun (int n) > int { return n * n; })(10) == 100, message: "called anonymous function"); + std.assert((fun (int n) > int -> n * n)(10) == 100, message: "called lambda function"); + std.assert(callThis(fun (int n) > int -> n * 2, arg: 2) == 4, message: "called a function from a function"); } fun mul(int a, int b) > int -> a * b; test "Any function can be an arrow function" { - assert(mul(a: 2, b: 2) == 4, message: "arrow function"); + std.assert(mul(a: 2, b: 2) == 4, message: "arrow function"); } \ No newline at end of file diff --git a/tests/014-import-lib.buzz b/tests/014-import-lib.buzz index 03e95f94..fe87c4b0 100644 --- a/tests/014-import-lib.buzz +++ b/tests/014-import-lib.buzz @@ -1,6 +1,6 @@ import print, assert from "std"; test "Using a function coming from a library" { - assert(true, message: "yeah!"); - print("wat"); + std.assert(true, message: "yeah!"); + std.print("wat"); } \ No newline at end of file diff --git a/tests/015-interpolation.buzz b/tests/015-interpolation.buzz index 55046107..412ce3b8 100644 --- a/tests/015-interpolation.buzz +++ b/tests/015-interpolation.buzz @@ -1,26 +1,26 @@ import "std"; test "Escape sequences" { - print("\{escaped interpolation}, \nhello\tworld, backslash \\ \"hey\""); + std.print("\{escaped interpolation}, \nhello\tworld, backslash \\ \"hey\""); } test "String interpolation" { str name = "joe"; int age = 12; - assert( + std.assert( "{"$"} hello {name} i'm {age} years old {3+4}" == "$ hello joe i'm 12 years old 7", message: "interpolation" ); - assert("not starting with a {name} {age} yeah!" + std.assert("not starting with a {name} {age} yeah!" == "not starting with a joe 12 yeah!", message: "interpolation order"); - assert("\60\61\62" == "<=>", message: "raw char"); + std.assert("\60\61\62" == "<=>", message: "raw char"); } test "Printing empty string" { - print(""); + std.print(""); } \ No newline at end of file diff --git a/tests/016-optionals.buzz b/tests/016-optionals.buzz index 73aa89d2..27d287a1 100644 --- a/tests/016-optionals.buzz +++ b/tests/016-optionals.buzz @@ -6,13 +6,13 @@ test "Optional force unwrapping with `!`" { | I think it's saner for it to not be catchable but to provides safe way to unwrap it str? hello = "hello world"; - assert(hello! == "hello world", message: "Could force unwrap an optional"); + std.assert(hello! == "hello world", message: "Could force unwrap an optional"); } test "Optional graceful unwrapping with `?`" { [int]? optList = [1, 2, 3]; - assert(optList?.len() == 3, message: "could unwrap optList"); + std.assert(optList?.len() == 3, message: "could unwrap optList"); } object Me { @@ -24,17 +24,17 @@ test "Optional chaining" { list = [1, 2, 3], }; - assert(me?.list?.len() == 3, message: "chaining optionals work"); + std.assert(me?.list?.len() == 3, message: "chaining optionals work"); Me? you = null; - assert(you?.list?.len() == null, message: "chaining optionals work"); + std.assert(you?.list?.len() == null, message: "chaining optionals work"); } test "Null coalescing operator" { str? hello = null; - assert(hello ?? "world" == "world", message: "null coalescing"); + std.assert(hello ?? "world" == "world", message: "null coalescing"); } test "Unwrap map subscript" { @@ -43,7 +43,7 @@ test "Unwrap map subscript" { "mo": "jo", }; - assert(map["yo"]?.len() == 2, message: "could unwrap map subscript"); + std.assert(map["yo"]?.len() == 2, message: "could unwrap map subscript"); } object You { @@ -55,7 +55,7 @@ test "Field access on map subscript" { "yo": You{} }; - assert(map["yo"]?.name == "joe", message: "could field access map subscript"); + std.assert(map["yo"]?.name == "joe", message: "could field access map subscript"); } object A { diff --git a/tests/017-for.buzz b/tests/017-for.buzz index dec8e08d..ba299e82 100644 --- a/tests/017-for.buzz +++ b/tests/017-for.buzz @@ -6,7 +6,7 @@ test "for loop" { sum = sum + i; } - assert(sum == 45, message: "for loop"); + std.assert(sum == 45, message: "for loop"); } test "multiple variable and expressions in for loop" { @@ -15,5 +15,5 @@ test "multiple variable and expressions in for loop" { sum = sum + i + j; } - assert(sum == 90, message: "multiple var loop"); + std.assert(sum == 90, message: "multiple var loop"); } diff --git a/tests/018-foreach.buzz b/tests/018-foreach.buzz index bc40a412..4e1716c0 100644 --- a/tests/018-foreach.buzz +++ b/tests/018-foreach.buzz @@ -8,14 +8,14 @@ test "foreach on list" { sum = sum + item; } - assert(sum == 6, message: "foreach on list"); + std.assert(sum == 6, message: "foreach on list"); } test "list.next" { [int] list = [1, 2, 3]; - assert(list.next(null) == 0, message: "calling next native"); - assert(list.next(0) == 1, message: "calling next native"); + std.assert(list.next(null) == 0, message: "calling next native"); + std.assert(list.next(0) == 1, message: "calling next native"); } test "foreach on map" { @@ -30,7 +30,7 @@ test "foreach on map" { sum = sum + value; } - assert(sum == 6, message: "foreach on map"); + std.assert(sum == 6, message: "foreach on map"); } enum Hey { @@ -45,7 +45,7 @@ test "foreach on enum" { sum = sum + case.value; } - assert(sum == 3, message: "foreach on enum"); + std.assert(sum == 3, message: "foreach on enum"); } test "foreach on str" { @@ -54,7 +54,7 @@ test "foreach on str" { hello = "{hello}{char}"; } - assert(hello == "hello world", message: "foreach on str"); + std.assert(hello == "hello world", message: "foreach on str"); } test "Omit key in foreach" { @@ -62,17 +62,17 @@ test "Omit key in foreach" { foreach (int n in [1, 2, 3]) { sum = sum + n; } - assert(sum == 6, message: "Could omit list key"); + std.assert(sum == 6, message: "Could omit list key"); str hello = ""; foreach (str char in "hello") { hello = "{hello}{char}"; } - assert(hello == "hello", message: "Could omit string key"); + std.assert(hello == "hello", message: "Could omit string key"); sum = 0; foreach (int n in {"hello": 1, "world": 2}) { sum = sum + n; } - assert(sum == 3, message: "Could omit map key"); + std.assert(sum == 3, message: "Could omit map key"); } \ No newline at end of file diff --git a/tests/019-is.buzz b/tests/019-is.buzz index 37d0b512..64534f5d 100644 --- a/tests/019-is.buzz +++ b/tests/019-is.buzz @@ -19,16 +19,16 @@ fun myFun(int id) > int { } test "`is` operator" { - assert(12 is int, message: "`is` on int"); - assert(true is bool, message: "`is` on bool"); - assert("yo" is str, message: "`is` on str"); + std.assert(12 is int, message: "`is` on int"); + std.assert(true is bool, message: "`is` on bool"); + std.assert("yo" is str, message: "`is` on str"); - assert(MyObj{} is MyObj, message: "`is` for an object instance"); - assert(MyEnum.one is MyEnum, message: "`is` for an enum instance"); - assert(myFun is Function(int id) > int, message: "`is` for a function"); + std.assert(MyObj{} is MyObj, message: "`is` for an object instance"); + std.assert(MyEnum.one is MyEnum, message: "`is` for an enum instance"); + std.assert(myFun is Function(int id) > int, message: "`is` for a function"); - assert([, 1,2,3] is [int], message: "`is` on a list"); - assert({, "one": 1} is {str: int}, message: "`is` on a map"); + std.assert([, 1,2,3] is [int], message: "`is` on a list"); + std.assert({, "one": 1} is {str: int}, message: "`is` on a map"); | TODO: should be `Function(MyObj) > bool` - assert(MyObj{}.bound is Function() > bool, message: "`is` on bound method"); + std.assert(MyObj{}.bound is Function() > bool, message: "`is` on bound method"); } \ No newline at end of file diff --git a/tests/021-upvalues.buzz b/tests/021-upvalues.buzz index cb7ad687..27da336d 100644 --- a/tests/021-upvalues.buzz +++ b/tests/021-upvalues.buzz @@ -4,7 +4,7 @@ fun upvals() > Function() { int upvalue = 12; str up = "up"; - return fun () > void -> print("{upvalue} {up}"); + return fun () > void -> std.print("{upvalue} {up}"); } test "Upvalues" { diff --git a/tests/022-io.buzz b/tests/022-io.buzz index 85e8e0cb..1e0a7ca4 100644 --- a/tests/022-io.buzz +++ b/tests/022-io.buzz @@ -3,40 +3,40 @@ import "io"; import "fs"; test "Write & read a file" { - File file = File.open("./hello.txt", mode: FileMode.write); + var file = io.File.open("./hello.txt", mode: io.FileMode.write); file.write("Hello World"); file.close(); | Now read it - File fileB = File.open("./hello.txt", mode: FileMode.read); + var fileB = io.File.open("./hello.txt", mode: io.FileMode.read); - assert(file.readAll() == "Hello World", message: "Could write and read a file"); + std.assert(file.readAll() == "Hello World", message: "Could write and read a file"); fileB.close(); - delete("./hello.txt"); + fs.delete("./hello.txt"); } test "Write on stdout" { - stdout.write("Hello World !\n"); + io.stdout.write("Hello World !\n"); } test "Read by lines" { - File file = File.open("./README.md", mode: FileMode.read); + var file = io.File.open("./README.md", mode: io.FileMode.read); for (int lines = 0, str? line = ""; line != null; line = file.readLine(), lines = lines + 1) { - print("{lines}: {line}"); + std.print("{lines}: {line}"); } file.close(); } test "Read" { - File file = File.open("./README.md", mode: FileMode.read); + var file = io.File.open("./README.md", mode: io.FileMode.read); - assert(file.read(18) == "

", message: "Can read n bytes"); + std.assert(file.read(18) == "

", message: "Can read n bytes"); file.close(); } \ No newline at end of file diff --git a/tests/023-std.buzz b/tests/023-std.buzz index e6e10489..546f142f 100644 --- a/tests/023-std.buzz +++ b/tests/023-std.buzz @@ -1,23 +1,23 @@ import "std"; -test "parseInt/Float" { - assert(parseInt("12") == 12, message: "Could parse int"); - assert(parseFloat("12.42") == 12.42, message: "Could parse float"); - assert(parseInt("not a number") == null, message: "Doesn't parse stupid shit"); +test "std.parseInt/Float" { + std.assert(std.parseInt("12") == 12, message: "Could parse int"); + std.assert(std.parseFloat("12.42") == 12.42, message: "Could parse float"); + std.assert(std.parseInt("not a number") == null, message: "Doesn't parse stupid shit"); - assert(toInt(23.34) == 23, message: "Could cast float to int"); - assert(toFloat(23) == 23.0, message: "Could cast int to float"); - assert(toUd(23) is ud, message: "Could cast int to ud"); - assert(toUd(23.0) is ud, message: "Could cast float to ud"); + std.assert(std.toInt(23.34) == 23, message: "Could cast float to int"); + std.assert(std.toFloat(23) == 23.0, message: "Could cast int to float"); + std.assert(std.toUd(23) is ud, message: "Could cast int to ud"); + std.assert(std.toUd(23.0) is ud, message: "Could cast float to ud"); - assert(parseUd("42") == toUd(42), message: "Could parse ud"); + std.assert(std.parseUd("42") == std.toUd(42), message: "Could parse ud"); } test "char" { - assert(char(65) == "A", message: "char"); + std.assert(std.char(65) == "A", message: "char"); } test "random" { - assert(random(min: 5, max: 10) >= 5, message: "random range"); - assert(random(max: 10) <= 10, message: "random range"); + std.assert(std.random(min: 5, max: 10) >= 5, message: "random range"); + std.assert(std.random(max: 10) <= 10, message: "random range"); } \ No newline at end of file diff --git a/tests/024-os.buzz b/tests/024-os.buzz index 768997e6..0f64cabb 100644 --- a/tests/024-os.buzz +++ b/tests/024-os.buzz @@ -2,24 +2,24 @@ import "std"; import "os" as os; test "os.env" { - assert(os.env("HOME") != null, message: "could get env variable"); + std.assert(os.env("HOME") != null, message: "could get env variable"); } test "os.time" { - assert(os.time() > 0, message: "Got time"); + std.assert(os.time() > 0, message: "Got time"); } test "os.tmpDir" { | TODO: replace by .len check - assert(os.tmpDir() != "", message: "Got system tmp dir"); + std.assert(os.tmpDir() != "", message: "Got system tmp dir"); } test "os.tmpFilename" { - assert(os.tmpFilename("buzz_test") != "", message: "Got tmp file name"); + std.assert(os.tmpFilename("buzz_test") != "", message: "Got tmp file name"); } test "os.execute" { - assert(os.execute(["./zig-out/bin/buzz", "--version"]) == 0, message: "Could execute a command"); + std.assert(os.execute(["./zig-out/bin/buzz", "--version"]) == 0, message: "Could execute a command"); } test "os.sleep" { diff --git a/tests/025-fs.buzz b/tests/025-fs.buzz index cf00ee72..7802f932 100644 --- a/tests/025-fs.buzz +++ b/tests/025-fs.buzz @@ -2,7 +2,7 @@ import "std"; import "fs" as fs; test "fs.cwd" { - assert(fs.currentDirectory() != "", message: "Could get cwd"); + std.assert(fs.currentDirectory() != "", message: "Could get cwd"); } test "mkDir/rm" { @@ -25,26 +25,26 @@ test "ls" { str anotherRandomLocal = "bye there!"; - assert(anotherRandomLocal == "bye there!", message: "foreach break is wrong"); + std.assert(anotherRandomLocal == "bye there!", message: "foreach break is wrong"); - assert(containsREADME, message: "Could list element in current directory"); + std.assert(containsREADME, message: "Could list element in current directory"); foreach (str el in fs.list("/doesnotexist") catch ["wentwrong"]) { - assert(el == "wentwrong", message: "Trying to list a non existent directory raised an error"); + std.assert(el == "wentwrong", message: "Trying to list a non existent directory raised an error"); } } test "move" { fs.move(source: "README.md", destination: "src/README.md"); - assert( + std.assert( fs.list("src").indexOf("README.md") != null, message: "Moved file to expected location" ); fs.move(source: "src/README.md", destination: "README.md"); - assert( + std.assert( fs.list(".").indexOf("README.md") != null, message: "Moved file to expected location" ); diff --git a/tests/026-break-continue.buzz b/tests/026-break-continue.buzz index 4a860e62..61b8ffae 100644 --- a/tests/026-break-continue.buzz +++ b/tests/026-break-continue.buzz @@ -10,7 +10,7 @@ test "break statement" { } } - assert(i == 3, message: "break"); + std.assert(i == 3, message: "break"); } test "continue statement" { @@ -25,5 +25,5 @@ test "continue statement" { i = i + 1; } - assert(i == 11, message: "break"); + std.assert(i == 11, message: "break"); } \ No newline at end of file diff --git a/tests/027-run-file.buzz b/tests/027-run-file.buzz index 33b625be..a8326e22 100644 --- a/tests/027-run-file.buzz +++ b/tests/027-run-file.buzz @@ -2,18 +2,18 @@ import "std"; import "io"; test "runFile" { - runFile("tests/utils/testing.buzz"); + io.runFile("tests/utils/testing.buzz"); - assert(true, message: "Could run a buzz file"); + std.assert(true, message: "Could run a buzz file"); } test "run non existent file" { bool errorRaised = false; try { - runFile("tests/utils/testingsldkfj.buzz"); + io.runFile("tests/utils/testingsldkfj.buzz"); } catch { errorRaised = true; } - assert(errorRaised, message: "Non existent file raised an error"); + std.assert(errorRaised, message: "Non existent file raised an error"); } \ No newline at end of file diff --git a/tests/028-math.buzz b/tests/028-math.buzz index 38b1a1cb..7cc0bb75 100644 --- a/tests/028-math.buzz +++ b/tests/028-math.buzz @@ -2,21 +2,21 @@ import "std"; import "math" as math; test "math" { - assert(math.abs(-12.234) == 12.234, message: "math.abs"); - assert(math.acos(0.1) == 1.4706289056333368, message: "math.acos"); - assert(math.asin(0.1) == 0.1001674211615598, message: "math.asin"); - assert(math.atan(0.1) == 0.09966865249116204, message: "math.atan"); - assert(math.ceil(12.234) == 13, message: "math.ceil"); - assert(math.cos(12.234) == 0.9452715049027691, message: "math.cos"); - assert(math.exp(12.234) == 205664.19575705, message: "math.exp"); - assert(math.floor(12.234) == 12, message: "math.floor"); - assert(math.sin(12.234) == -0.3262848173281347, message: "math.sin"); - assert(math.sqrt(12.234) == 3.4977135388707863, message: "math.sqrt"); - assert(math.tan(12.234) == -0.34517576763481983, message: "math.tan"); + std.assert(math.abs(-12.234) == 12.234, message: "math.abs"); + std.assert(math.acos(0.1) == 1.4706289056333368, message: "math.acos"); + std.assert(math.asin(0.1) == 0.1001674211615598, message: "math.asin"); + std.assert(math.atan(0.1) == 0.09966865249116204, message: "math.atan"); + std.assert(math.ceil(12.234) == 13, message: "math.ceil"); + std.assert(math.cos(12.234) == 0.9452715049027691, message: "math.cos"); + std.assert(math.exp(12.234) == 205664.19575705, message: "math.exp"); + std.assert(math.floor(12.234) == 12, message: "math.floor"); + std.assert(math.sin(12.234) == -0.3262848173281347, message: "math.sin"); + std.assert(math.sqrt(12.234) == 3.4977135388707863, message: "math.sqrt"); + std.assert(math.tan(12.234) == -0.34517576763481983, message: "math.tan"); - assert(math.minInt(a: 12, b: 124) == 12, message: "math.min"); - assert(math.maxInt(a: 12, b: 124) == 124, message: "math.max"); + std.assert(math.minInt(a: 12, b: 124) == 12, message: "math.min"); + std.assert(math.maxInt(a: 12, b: 124) == 124, message: "math.max"); - assert(math.deg(2.0) == 114.59155902616439, message: "math.deg"); - assert(math.rad(math.deg(2.0)) == 2, message: "math.rad"); + std.assert(math.deg(2.0) == 114.59155902616439, message: "math.deg"); + std.assert(math.rad(math.deg(2.0)) == 2, message: "math.rad"); } \ No newline at end of file diff --git a/tests/029-default-arguments.buzz b/tests/029-default-arguments.buzz index a263770f..6c46613d 100644 --- a/tests/029-default-arguments.buzz +++ b/tests/029-default-arguments.buzz @@ -4,9 +4,9 @@ fun hey(str name = "Joe", int age = 12, str? father, int fourth = 1) > str -> "Hello {name} you're {age} {father} {fourth}"; test "function default arguments" { - assert(hey("John") == "Hello John you're 12 null 1", message: "Could reorder or omit argument"); - assert(hey(age: 25) == "Hello Joe you're 25 null 1", message: "Could reorder or omit argument"); - assert(hey(father: "Doe") == "Hello Joe you're 12 Doe 1", message: "Could reorder or omit argument"); - assert(hey(fourth: 42) == "Hello Joe you're 12 null 42", message: "Could reorder or omit argument"); - assert(hey(fourth: 12, age: 44) == "Hello Joe you're 44 null 12", message: "Could reorder or omit argument"); + std.assert(hey("John") == "Hello John you're 12 null 1", message: "Could reorder or omit argument"); + std.assert(hey(age: 25) == "Hello Joe you're 25 null 1", message: "Could reorder or omit argument"); + std.assert(hey(father: "Doe") == "Hello Joe you're 12 Doe 1", message: "Could reorder or omit argument"); + std.assert(hey(fourth: 42) == "Hello Joe you're 12 null 42", message: "Could reorder or omit argument"); + std.assert(hey(fourth: 12, age: 44) == "Hello Joe you're 44 null 12", message: "Could reorder or omit argument"); } \ No newline at end of file diff --git a/tests/030-str.buzz b/tests/030-str.buzz index a133fc51..e0febd38 100644 --- a/tests/030-str.buzz +++ b/tests/030-str.buzz @@ -1,47 +1,47 @@ import "std"; test "str subscript" { - assert("hello world"[1] == "e", message: "str subscript"); + std.assert("hello world"[1] == "e", message: "str subscript"); } test "str.len" { - assert("hello world".len() == 11, message: "str.len"); + std.assert("hello world".len() == 11, message: "str.len"); } test "str.byte" { - assert("hello world".byte(1) == 101, message: "str.byte"); + std.assert("hello world".byte(1) == 101, message: "str.byte"); } test "str.indexOf" { - assert("hello world".indexOf("world") == 6, message: "str.indexOf"); - assert("hello world".indexOf("moon") == null, message: "str.indexOf"); + std.assert("hello world".indexOf("world") == 6, message: "str.indexOf"); + std.assert("hello world".indexOf("moon") == null, message: "str.indexOf"); } test "str.split" { [str] splits = "one,two,three".split(","); - assert(splits[0] == "one" and splits[1] == "two" and splits[2] == "three", message: "str.split"); + std.assert(splits[0] == "one" and splits[1] == "two" and splits[2] == "three", message: "str.split"); } test "str.sub" { - assert("hello world".sub(6) == "world", message: "str.sub"); - assert("hello world".sub(0, len: 5) == "hello", message: "str.sub"); + std.assert("hello world".sub(6) == "world", message: "str.sub"); + std.assert("hello world".sub(0, len: 5) == "hello", message: "str.sub"); } test "base64" { - assert("hello world".encodeBase64() == "aGVsbG8gd29ybGQ=", message: "could encode in b64"); - assert("aGVsbG8gd29ybGQ=".decodeBase64() == "hello world", message: "could encode in b64"); + std.assert("hello world".encodeBase64() == "aGVsbG8gd29ybGQ=", message: "could encode in b64"); + std.assert("aGVsbG8gd29ybGQ=".decodeBase64() == "hello world", message: "could encode in b64"); } test "upper/lower" { - assert("hello world!".upper() == "HELLO WORLD!", message: "upper"); - assert("HellO WorlD!".lower() == "hello world!", message: "lower"); + std.assert("hello world!".upper() == "HELLO WORLD!", message: "upper"); + std.assert("HellO WorlD!".lower() == "hello world!", message: "lower"); } test "hex/bin" { - assert("c3fcd3d76192e4007dfb496cca67e13b".bin().hex() == "c3fcd3d76192e4007dfb496cca67e13b", message: "hex/bin"); + std.assert("c3fcd3d76192e4007dfb496cca67e13b".bin().hex() == "c3fcd3d76192e4007dfb496cca67e13b", message: "hex/bin"); } test "trim" { - assert(" hello world \t\n".trim() == "hello world", message: "could trim str"); + std.assert(" hello world \t\n".trim() == "hello world", message: "could trim str"); } \ No newline at end of file diff --git a/tests/031-json.buzz b/tests/031-json.buzz index 3359ead7..935c06fe 100644 --- a/tests/031-json.buzz +++ b/tests/031-json.buzz @@ -7,15 +7,15 @@ test "Json.encode" { "bye": 42, }; - assert( - jsonEncode(Boxed.init(data)) == `\{"hello":"world","bye":42}`, + std.assert( + serialize.jsonEncode(serialize.Boxed.init(data)) == `\{"hello":"world","bye":42}`, message: "valid encode" ); } test "Json.decode" { - assert( - jsonDecode(`[ -12, true, "hello" ]`).listValue()[2].string() == "hello", + std.assert( + serialize.jsonDecode(`[ -12, true, "hello" ]`).listValue()[2].string() == "hello", message: "could decode simple JSON" ); } @@ -32,7 +32,7 @@ test "Boxed.q" { } }; - Boxed boxed = Boxed.init(data); + var boxed = serialize.Boxed.init(data); - assert(boxed.q(["submap", "subsubmap", "one"]).integer() == 1, message: "Boxed.q"); + std.assert(boxed.q(["submap", "subsubmap", "one"]).integer() == 1, message: "Boxed.q"); } \ No newline at end of file diff --git a/tests/032-debug.buzz b/tests/032-debug.buzz index 42ad275f..959b61b1 100644 --- a/tests/032-debug.buzz +++ b/tests/032-debug.buzz @@ -7,12 +7,12 @@ import "serialize"; | str source = debug.ast(` | import \"std\"; | -| fun main([str] _) > void -> print(\"hello world\"); +| fun main([str] _) > void -> std.print(\"hello world\"); | `, scriptName: "test"); | | Boxed jsonAST = jsonDecode(source); | -| print(jsonEncode(jsonAST)); +| std.print(jsonEncode(jsonAST)); | } enum MyEnum { diff --git a/tests/033-invoke.buzz b/tests/033-invoke.buzz index de020b29..ce891638 100644 --- a/tests/033-invoke.buzz +++ b/tests/033-invoke.buzz @@ -4,7 +4,7 @@ object A { [A] list, fun hello() > A { - print("hello"); + std.print("hello"); return this; } } diff --git a/tests/034-scope.buzz b/tests/034-scope.buzz index 7bdb9e0d..daa69b63 100644 --- a/tests/034-scope.buzz +++ b/tests/034-scope.buzz @@ -11,20 +11,20 @@ test "locals inside a foreach" { str newnew = "yoyo"; str oldold = "lolo"; - assert(new == "yo", message: "locals are ok"); - assert(old == "lo", message: "locals are ok"); - assert(newnew == "yoyo", message: "locals are ok"); - assert(oldold == "lolo", message: "locals are ok"); + std.assert(new == "yo", message: "locals are ok"); + std.assert(old == "lo", message: "locals are ok"); + std.assert(newnew == "yoyo", message: "locals are ok"); + std.assert(oldold == "lolo", message: "locals are ok"); } - assert(hello == ""); + std.assert(hello == ""); } for (int i = 0; i < 3; i = i + 1) { str new = "yo"; str old = "lo"; - assert(new == "yo", message: "locals are ok"); - assert(old == "lo", message: "locals are ok"); + std.assert(new == "yo", message: "locals are ok"); + std.assert(old == "lo", message: "locals are ok"); } } \ No newline at end of file diff --git a/tests/035-const-expr.buzz b/tests/035-const-expr.buzz index 1be23eb4..559f98d4 100644 --- a/tests/035-const-expr.buzz +++ b/tests/035-const-expr.buzz @@ -1,10 +1,10 @@ import "std"; fun hello([str] name = ["John", "Doe"], {str: str} address = { "street": "somewhere street", "town": "New York" }) > void { - assert(name.len() == 2, message: "default arg is clone of the default value"); - assert(address.size() == 2, message: "default arg is clone of the default value"); + std.assert(name.len() == 2, message: "default arg is clone of the default value"); + std.assert(address.size() == 2, message: "default arg is clone of the default value"); - print("Hello I'm {name[0]} {name[1]} I live at {address["street"]} in {address["town"]}"); + std.print("Hello I'm {name[0]} {name[1]} I live at {address["street"]} in {address["town"]}"); name.append("Yolo"); address["country"] = "US"; @@ -22,16 +22,16 @@ test "Constant expression" { A a = A{}; A b = A{}; - assert(a.list != b.list, message: "object default value were cloned"); - assert(a.map != b.map, message: "object default value were cloned"); + std.assert(a.list != b.list, message: "object default value were cloned"); + std.assert(a.map != b.map, message: "object default value were cloned"); a.list.append(4); - assert(a.list.len() == 4, message: "object default value were cloned"); - assert(b.list.len() == 3, message: "object default value were cloned"); + std.assert(a.list.len() == 4, message: "object default value were cloned"); + std.assert(b.list.len() == 3, message: "object default value were cloned"); a.map["lo"] = 4; - assert(a.map.size() == 2, message: "object default value were cloned"); - assert(b.map.size() == 1, message: "object default value were cloned"); + std.assert(a.map.size() == 2, message: "object default value were cloned"); + std.assert(b.map.size() == 1, message: "object default value were cloned"); } \ No newline at end of file diff --git a/tests/036-pattern.buzz b/tests/036-pattern.buzz index 0397b9ae..e06b44cd 100644 --- a/tests/036-pattern.buzz +++ b/tests/036-pattern.buzz @@ -5,9 +5,9 @@ test "pattern.match" { [str]? results = pattern.match("All i want to say is hello joe! hello mundo!"); - assert(results?.len() == 2, message: "1 match and 1 capture"); - assert(results![0] == "hello joe", message: "first is match"); - assert(results![1] == "joe", message: "second is capture"); + std.assert(results?.len() == 2, message: "1 match and 1 capture"); + std.assert(results![0] == "hello joe", message: "first is match"); + std.assert(results![1] == "joe", message: "second is capture"); } test "pattern.matchAll" { @@ -15,24 +15,24 @@ test "pattern.matchAll" { [[str]]? results = pattern.matchAll("All i want to say is hello joe!\nhello mundo!\nAnd hello neighbor..."); - assert(results?.len() == 3, message: "found 3 matches"); - assert(results![2].len() == 2, message: "1 match and 1 capture"); - assert(results![2][1] == "neighbor", message: "capture is correct"); + std.assert(results?.len() == 3, message: "found 3 matches"); + std.assert(results![2].len() == 2, message: "1 match and 1 capture"); + std.assert(results![2][1] == "neighbor", message: "capture is correct"); } test "Escaped pattern delimiter" { pat pattern = $"hello \" world"; - assert("{pattern}" == "hello \" world", message: "delimiter was properly escaped"); + std.assert("{pattern}" == "hello \" world", message: "delimiter was properly escaped"); } test "replace" { - assert( + std.assert( $"world".replace("All i want to say is hello world!", with: "mundo") == "All i want to say is hello mundo!", message: "replace" ); - assert( + std.assert( $"alright".replaceAll("he says: alright, alright, alright!", with: "check") == "he says: check, check, check!", message: "replaceAll" ); diff --git a/tests/037-dead-branches.buzz b/tests/037-dead-branches.buzz index 31d2ec7f..29765229 100644 --- a/tests/037-dead-branches.buzz +++ b/tests/037-dead-branches.buzz @@ -2,26 +2,26 @@ import "std"; test "if" { if (true) { - assert(true, message: "only this branch should be generated"); + std.assert(true, message: "only this branch should be generated"); } else { - assert(false, message: "unreachable"); + std.assert(false, message: "unreachable"); } } test "foreach" { foreach (str _ in {}) { - assert(false, message: "unreachable"); + std.assert(false, message: "unreachable"); } } test "while" { while (false) { - assert(false, message: "unreachable"); + std.assert(false, message: "unreachable"); } } test "for" { for (int i = 0; false; i = i + 1) { - assert(false, message: "unreachable"); + std.assert(false, message: "unreachable"); } } \ No newline at end of file diff --git a/tests/038-fibers.buzz b/tests/038-fibers.buzz index e6e0c0f0..30a5502d 100644 --- a/tests/038-fibers.buzz +++ b/tests/038-fibers.buzz @@ -11,19 +11,19 @@ test "fiber" { sum = sum + resume counter ?? 0; } - assert(counter.over(), message: "Fiber should be over now"); + std.assert(counter.over(), message: "Fiber should be over now"); | resolve runs fiber until it's over and dismiss any yielded value along the way - assert(resolve counter == "Counting is done!", message: "Fiber is over we get its return value"); - assert(sum == 45, message: "Sum is good"); + std.assert(resolve counter == "Counting is done!", message: "Fiber is over we get its return value"); + std.assert(sum == 45, message: "Sum is good"); - assert(resolve &count(10) == "Counting is done!", message: "Resolve without any resume"); + std.assert(resolve &count(10) == "Counting is done!", message: "Resolve without any resume"); } | returns str, yields int fun count(int n) > str *> int? { - assert(currentFiber() is fib, message: "Can get current fiber"); - assert(!currentFiber().isMain(), message: "Can know if fiber is main one"); + std.assert(std.currentFiber() is fib, message: "Can get current fiber"); + std.assert(!std.currentFiber().isMain(), message: "Can know if fiber is main one"); for (int i = 0; i < n; i = i + 1) { | error or yield is ignored if not called with a async call? @@ -46,7 +46,7 @@ fun caughFiberFail() > bool !> str { } test "Throw inside a fiber" { - assert(caughFiberFail() catch true, message: "Caught an error from a fiber"); + std.assert(caughFiberFail() catch true, message: "Caught an error from a fiber"); } fun closedUpvalue() > Function() > str { @@ -60,11 +60,11 @@ test "Opened upvalue in fiber" { Function() > str fiberFn = fun () > str -> "hello {upvalue}"; - assert(resolve &fiberFn() == "hello world", message: "Fiber could use an opened upvalue"); + std.assert(resolve &fiberFn() == "hello world", message: "Fiber could use an opened upvalue"); } test "Closed upvalue in fiber" { - assert(resolve &closedUpvalue()() == "hello joe", message: "Fiber could use a closed upvalue"); + std.assert(resolve &closedUpvalue()() == "hello joe", message: "Fiber could use a closed upvalue"); } test "Wrapping call inside complex expressions" { @@ -72,5 +72,5 @@ test "Wrapping call inside complex expressions" { "hello": fun () > str -> "hello world", }; - assert(resolve &map["hello"]?() == "hello world", message:"Could warp function call in a complex expression"); + std.assert(resolve &map["hello"]?() == "hello world", message:"Could warp function call in a complex expression"); } \ No newline at end of file diff --git a/tests/039-buffer.buzz b/tests/039-buffer.buzz index 1dde17aa..9567017d 100644 --- a/tests/039-buffer.buzz +++ b/tests/039-buffer.buzz @@ -1,8 +1,8 @@ import "std"; -import "buffer"; +import "buffer" as _; test "Reading and writing in a buffer" { - Buffer buffer = Buffer.init(); + var buffer = Buffer.init(); buffer.writeInt("hello world".len()); buffer.write("hello world"); @@ -16,19 +16,19 @@ test "Reading and writing in a buffer" { 1, | true ]; foreach (int i, str char in buffer.toString()) { - assert(expected[i] == char.byte(0), message: "Buffer has expected content"); + std.assert(expected[i] == char.byte(0), message: "Buffer has expected content"); } - assert(buffer.len() == expected.len(), message: "wrote expected number of bytes"); + std.assert(buffer.len() == expected.len(), message: "wrote expected number of bytes"); const int len = buffer.readInt() ?? -1; - assert(len == 11, message: "could read number"); + std.assert(len == 11, message: "could read number"); - assert(buffer.read(len) == "hello world", message: "could read n bytes"); - assert(buffer.readFloat() == 1238.324, message: "could read float"); - assert(buffer.readBoolean() == true, message: "could read boolean"); + std.assert(buffer.read(len) == "hello world", message: "could read n bytes"); + std.assert(buffer.readFloat() == 1238.324, message: "could read float"); + std.assert(buffer.readBoolean() == true, message: "could read boolean"); buffer.empty(); - assert(buffer.len() == 0, message: "could empty buffer"); + std.assert(buffer.len() == 0, message: "could empty buffer"); } \ No newline at end of file diff --git a/tests/040-bitwise.buzz b/tests/040-bitwise.buzz index b467afbe..a4f754d8 100644 --- a/tests/040-bitwise.buzz +++ b/tests/040-bitwise.buzz @@ -1,10 +1,10 @@ import "std"; test "Bitwise" { - assert(15 << 3 == 120, message: "<<"); - assert(15 >> 3 == 1, message: ">>"); - assert(15 ^ 3 == 12, message: "^"); - assert(15 \ 3 == 15, message: "\\"); - assert(~15 == -16, message: "~"); - assert(12 & 23 == 4, message: "&"); + std.assert(15 << 3 == 120, message: "<<"); + std.assert(15 >> 3 == 1, message: ">>"); + std.assert(15 ^ 3 == 12, message: "^"); + std.assert(15 \ 3 == 15, message: "\\"); + std.assert(~15 == -16, message: "~"); + std.assert(12 & 23 == 4, message: "&"); } \ No newline at end of file diff --git a/tests/041-iterator.buzz b/tests/041-iterator.buzz index 8e43a236..fad38b15 100644 --- a/tests/041-iterator.buzz +++ b/tests/041-iterator.buzz @@ -17,7 +17,7 @@ test "finobacci generator" { [int] suite = [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]; int i = 0; foreach (int n in &fibonnaci(10)) { - assert(suite[i] == n, message: "could iterate over fiber"); + std.assert(suite[i] == n, message: "could iterate over fiber"); i = i + 1; } @@ -40,6 +40,6 @@ test "dot async call" { var hello = Hello{}; foreach (int i in &hello.range()) { - print("i {i}"); + std.print("i {i}"); } } \ No newline at end of file diff --git a/tests/042-anonymous-objects.buzz b/tests/042-anonymous-objects.buzz index b206dc0e..e57c13aa 100644 --- a/tests/042-anonymous-objects.buzz +++ b/tests/042-anonymous-objects.buzz @@ -12,8 +12,8 @@ test "Anonymous objects" { | Two anonymous type matches obj{ str name, int age } _ = info; - assert(info.name == "Joe" and info.age == 36, message: "Could declare, instanciate and acces anonymous objects"); - assert(info is obj{ str name, int age }, message: "Type safety works with anonymous object"); + std.assert(info.name == "Joe" and info.age == 36, message: "Could declare, instanciate and acces anonymous objects"); + std.assert(info is obj{ str name, int age }, message: "Type safety works with anonymous object"); } fun getPayload::(T data) > obj{ T data } { @@ -25,5 +25,5 @@ fun getPayload::(T data) > obj{ T data } { test "Anonymous object with generics" { obj{ int data } payload = getPayload::(42); - assert(payload.data == 42, message: "Could use anonymous object with generic"); + std.assert(payload.data == 42, message: "Could use anonymous object with generic"); } \ No newline at end of file diff --git a/tests/044-break-continue.buzz b/tests/044-break-continue.buzz index c0e2bd55..a060bf49 100644 --- a/tests/044-break-continue.buzz +++ b/tests/044-break-continue.buzz @@ -13,7 +13,7 @@ test "continue properly jumps and closes scope" { str anotherRandomLocal = "bye there"; - assert(anotherRandomLocal == "bye there", message: "continue properly closed revelant scopes"); + std.assert(anotherRandomLocal == "bye there", message: "continue properly closed revelant scopes"); } test "break properly jumps and closes scope" { @@ -30,5 +30,5 @@ test "break properly jumps and closes scope" { str anotherRandomLocal = "bye there"; - assert(anotherRandomLocal == "bye there", message: "break properly closed revelant scopes"); + std.assert(anotherRandomLocal == "bye there", message: "break properly closed revelant scopes"); } \ No newline at end of file diff --git a/tests/045-mutual-import.buzz b/tests/045-mutual-import.buzz index 5a99dffb..83b647b0 100644 --- a/tests/045-mutual-import.buzz +++ b/tests/045-mutual-import.buzz @@ -3,8 +3,8 @@ import "tests/utils/import-b"; import "tests/utils/import-a"; test "Mutual import" { - print("t: {Hello}"); - printClass(); - print("{hello}"); - assert(hello is Hello, message: "multiple import of the same script produce the same globals"); + std.print("t: {a.Hello}"); + b.printClass(); + std.print("{b.hello}"); + std.assert(b.hello is a.Hello, message: "multiple import of the same script produce the same globals"); } \ No newline at end of file diff --git a/tests/046-try-catch.buzz b/tests/046-try-catch.buzz index 750a362e..7facfef9 100644 --- a/tests/046-try-catch.buzz +++ b/tests/046-try-catch.buzz @@ -10,7 +10,7 @@ fun partialCatch() > void !> str { throw 12; } catch (int _) { - assert(false, message: "unreachable"); + std.assert(false, message: "unreachable"); } } @@ -38,24 +38,24 @@ test "Try catch" { partialCatch(); - assert(false, message: "unreachable"); + std.assert(false, message: "unreachable"); } catch (str error) { str _ = "a local in catch clause"; - assert(error == "Yolo", message: "caught error"); + std.assert(error == "Yolo", message: "caught error"); } catch (int _) { - assert(false, message: "unreachable"); + std.assert(false, message: "unreachable"); } catch { - assert(false, message: "unreachable"); + std.assert(false, message: "unreachable"); } str afterLocal = "bye"; - assert(setme == "yes", message: "error was handled and code continues"); + std.assert(setme == "yes", message: "error was handled and code continues"); - assert(returnFromCatch() == 21, message: "return from catch clause works"); + std.assert(returnFromCatch() == 21, message: "return from catch clause works"); - assert(afterLocal == "bye", message: "catch closed its scope"); + std.assert(afterLocal == "bye", message: "catch closed its scope"); } test "catch any catches everything" { @@ -64,8 +64,8 @@ test "catch any catches everything" { willFail(); } catch (any error) { caught = true; - assert(error is str, message: "Could cath any error"); + std.assert(error is str, message: "Could cath any error"); } - assert(caught, message: "Could catch any error"); + std.assert(caught, message: "Could catch any error"); } \ No newline at end of file diff --git a/tests/047-if-arrow.buzz b/tests/047-if-arrow.buzz index dca572c6..42977559 100644 --- a/tests/047-if-arrow.buzz +++ b/tests/047-if-arrow.buzz @@ -5,10 +5,10 @@ test "If arrow" { str? optS = "hello"; if (opt -> _) { - assert(false, message: "unreachable"); + std.assert(false, message: "unreachable"); } if (optS -> unwrapped) { - assert(unwrapped == "hello", message: "Could if-arrow unwrap"); + std.assert(unwrapped == "hello", message: "Could if-arrow unwrap"); } } \ No newline at end of file diff --git a/tests/048-generics.buzz b/tests/048-generics.buzz index b1c65fb3..e5f68f99 100644 --- a/tests/048-generics.buzz +++ b/tests/048-generics.buzz @@ -5,7 +5,7 @@ fun count::([T] list) > int { } test "Simple generic" { - assert(count::([1, 2, 3]) == 3, message: "could use generics"); + std.assert(count::([1, 2, 3]) == 3, message: "could use generics"); } fun extractList::(obj{ [T] list } data) > [T] { @@ -15,7 +15,7 @@ fun extractList::(obj{ [T] list } data) > [T] { test "Generic within anonymous object" { [int] list = [1, 2, 3]; - assert(extractList::(.{ list = list }) == list, message: "could use generic within anonymous object"); + std.assert(extractList::(.{ list = list }) == list, message: "could use generic within anonymous object"); } fun countMap::({K: V} map) > int { @@ -29,7 +29,7 @@ test "Multiple generic types" { "three": 3, }; - assert(countMap::(map) == 3, message: "could use multiple generic types"); + std.assert(countMap::(map) == 3, message: "could use multiple generic types"); } fun extractMap::(obj{ {K: V} map } data) > {K: V} { @@ -43,7 +43,7 @@ test "Generic within anonymous object and map" { "three": 3, }; - assert(extractMap::(.{ map = map }) == map, message: "could use generic within anonymous object"); + std.assert(extractMap::(.{ map = map }) == map, message: "could use generic within anonymous object"); } fun countShuffleGenerics::() > Function([A] a, [B] b) > int { @@ -54,7 +54,7 @@ test "Generic in lambda function definition" { [str] a = ["one", "two", "three"]; [int] b = [1, 2, 3]; - assert(countShuffleGenerics::()(a, b: b) == 6, message: "could use generic in lambda function definition"); + std.assert(countShuffleGenerics::()(a, b: b) == 6, message: "could use generic in lambda function definition"); } fun genericReturn::(T value) > T { @@ -62,7 +62,7 @@ fun genericReturn::(T value) > T { } test "generic return" { - assert(genericReturn::(12) == 12, message: "could use return of generic type"); + std.assert(genericReturn::(12) == 12, message: "could use return of generic type"); } fun fiber::([T] data) > void *> T? { @@ -79,12 +79,12 @@ test "Generic with fibers" { sum = sum + resume f ?? 0; } - assert(sum == 6, message: "could user generic in fiber definition"); + std.assert(sum == 6, message: "could user generic in fiber definition"); } test "Generics in placeholders" { - assert( + std.assert( countAgain::([1, 2, 3]) == 3, message: "Could use generics with placeholders" ); @@ -99,7 +99,7 @@ fun doubleGeneric::(Function::() > int lambda) > int { } test "Generic with generic lambda parameter" { - assert( + std.assert( doubleGeneric::( fun::() > int -> 12 ) == 12, diff --git a/tests/049-multiline-strings.buzz b/tests/049-multiline-strings.buzz index 5de5e1ca..6752d0aa 100644 --- a/tests/049-multiline-strings.buzz +++ b/tests/049-multiline-strings.buzz @@ -10,8 +10,8 @@ test "Multiline strings" { `} }`; - Boxed json = jsonDecode(multi); + var json = serialize.jsonDecode(multi); - assert(json.q(["yes"]).integer() == 15, message: "multiline string is valid"); - assert(json.q(["another"]).string() == "one", message: "multiline string is valid"); + std.assert(json.q(["yes"]).integer() == 15, message: "multiline string is valid"); + std.assert(json.q(["another"]).string() == "one", message: "multiline string is valid"); } \ No newline at end of file diff --git a/tests/050-protocols.buzz b/tests/050-protocols.buzz index e7aed257..bf7a0770 100644 --- a/tests/050-protocols.buzz +++ b/tests/050-protocols.buzz @@ -48,7 +48,7 @@ test "Protocols" { name = "bandit", }; - assert(bob.greater(joe), message: "could implement protocol"); + std.assert(bob.greater(joe), message: "could implement protocol"); Nameable nameable = bandit; nameable = joe; @@ -59,20 +59,20 @@ test "Protocols" { item.rename(newNames[i]); } - assert(bandit.name == "Chili", message: "could call protocol method"); - assert(joe.name == "Nick", message: "could call protocol method"); + std.assert(bandit.name == "Chili", message: "could call protocol method"); + std.assert(joe.name == "Nick", message: "could call protocol method"); {Nameable: bool} map = { bandit: true, joe: false, }; - assert(map[joe] == false, message: "could hold protocol as map key"); + std.assert(map[joe] == false, message: "could hold protocol as map key"); {str: Nameable} mapValue = { "bandit": bandit, "joe": joe, }; - assert(mapValue["joe"] == joe, message: "could hold protocol as map value"); + std.assert(mapValue["joe"] == joe, message: "could hold protocol as map value"); } \ No newline at end of file diff --git a/tests/051-functional.buzz b/tests/051-functional.buzz index 8d96f443..1f9606b5 100644 --- a/tests/051-functional.buzz +++ b/tests/051-functional.buzz @@ -8,7 +8,7 @@ test "list.forEach" { sum = sum + element; }); - assert(sum == 10, message: "could use list.forEach"); + std.assert(sum == 10, message: "could use list.forEach"); } test "list.map" { @@ -16,7 +16,7 @@ test "list.map" { [str] mapped = data.map::(fun (int _, int element) -> "{element}"); - assert(mapped.join(", ") == "1, 2, 3, 4", message: "could use map"); + std.assert(mapped.join(", ") == "1, 2, 3, 4", message: "could use map"); } test "list.filter" { @@ -24,7 +24,7 @@ test "list.filter" { [int] odd = data.filter(fun (int _, int element) -> element % 2 != 0); - assert(odd.join(", ") == "1, 3", message: "could use filter"); + std.assert(odd.join(", ") == "1, 3", message: "could use filter"); } test "list.reduce" { @@ -35,7 +35,7 @@ test "list.reduce" { initial: 0 ); - assert(sum == 10, message: "could use reduce"); + std.assert(sum == 10, message: "could use reduce"); } test "list.sort" { @@ -44,7 +44,7 @@ test "list.sort" { _ = data.sort(fun (int left, int right) -> left < right); foreach (int i, int value in [-3, 0, 1, 3, 10, 12]) { - assert(data[i] == value, message: "list is not ordered"); + std.assert(data[i] == value, message: "list is not ordered"); } } @@ -61,7 +61,7 @@ test "map.forEach" { fun (str _, int value) > void -> sum = sum + value ); - assert(sum == 11, message: "could use map.forEach"); + std.assert(sum == 11, message: "could use map.forEach"); } test "map.map" { @@ -78,7 +78,7 @@ test "map.map" { ); foreach (str key, int value in map) { - assert(inverted[value] == key, message: "Could use map.map"); + std.assert(inverted[value] == key, message: "Could use map.map"); } } @@ -94,7 +94,7 @@ test "map.filter" { fun (str _, int value) -> value % 2 != 0 ); - assert(filtered["two"] == null, message: "Could use map.filter"); + std.assert(filtered["two"] == null, message: "Could use map.filter"); } test "map.reduce" { @@ -110,7 +110,7 @@ test "map.reduce" { initial: 0 ); - assert(sum == 11, message: "could use reduce"); + std.assert(sum == 11, message: "could use reduce"); } test "map.sort" { @@ -129,7 +129,7 @@ test "map.sort" { [str] ordered = [ "one", "two", "three", "five" ]; int i = 0; foreach (str key in map.keys()) { - assert(ordered[i] == key, message: "Could sort map"); + std.assert(ordered[i] == key, message: "Could sort map"); i = i + 1; } diff --git a/tests/052-inline-if.buzz b/tests/052-inline-if.buzz index d65ebaa1..298d5b59 100644 --- a/tests/052-inline-if.buzz +++ b/tests/052-inline-if.buzz @@ -3,11 +3,11 @@ import "std"; test "ternary" { int value = if (true) 12 else 0; - assert(value == 12, message: "could use constant inline if"); + std.assert(value == 12, message: "could use constant inline if"); value = if ("hello".len() == 2) 0 else 12; - assert(value == 12, message: "could use inline if"); + std.assert(value == 12, message: "could use inline if"); } test "multiple branches" { @@ -20,13 +20,13 @@ test "multiple branches" { else null; - assert(expr == "yolo", message: "Could use multiple branches with inline if"); + std.assert(expr == "yolo", message: "Could use multiple branches with inline if"); } test "inline if in expression" { int value = 12; - assert( + std.assert( (if (value == 14) "hello" else if (value == 12) diff --git a/tests/053-range.buzz b/tests/053-range.buzz index e17b49e5..a68bd668 100644 --- a/tests/053-range.buzz +++ b/tests/053-range.buzz @@ -3,23 +3,23 @@ import "std"; test "Range" { int limit = 10; [int] range = 0..limit; - assert(range.len() == 10, message: "Could create list from range"); + std.assert(range.len() == 10, message: "Could create list from range"); int sum = 0; foreach (int n in 0..10) { sum = sum + n; } - assert(sum == 45, message: "Could iterate over range"); + std.assert(sum == 45, message: "Could iterate over range"); } test "Inverted range" { int limit = 0; [int] range = 10..limit; - assert(range.len() == 10, message: "Could create list from inverted range"); + std.assert(range.len() == 10, message: "Could create list from inverted range"); int sum = 0; foreach (int n in 10..0) { sum = sum + n; } - assert(sum == 55, message: "Could iterate over inverted range"); + std.assert(sum == 55, message: "Could iterate over inverted range"); } \ No newline at end of file diff --git a/tests/056-crypto.buzz b/tests/056-crypto.buzz index 2bd78167..77a2d73b 100644 --- a/tests/056-crypto.buzz +++ b/tests/056-crypto.buzz @@ -1,23 +1,23 @@ import "std"; -import "crypto"; +import "crypto" as _; test "hash" { - assert( + std.assert( "c3fcd3d76192e4007dfb496cca67e13b" == hash(HashAlgorithm.Md5, data: "abcdefghijklmnopqrstuvwxyz").hex(), message: "md5" ); - assert( + std.assert( "a9993e364706816aba3e25717850c26c9cd0d89d" == hash(HashAlgorithm.Sha1, data: "abc").hex(), message: "sha1" ); - assert( + std.assert( "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad" == hash(HashAlgorithm.Sha256, data: "abc").hex(), message: "sha256" ); - assert( + std.assert( "3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532" == hash(HashAlgorithm.Sha3256, data: "abc").hex(), message: "sha3-256" ); diff --git a/tests/057-any.buzz b/tests/057-any.buzz index 383ab726..b06a917b 100644 --- a/tests/057-any.buzz +++ b/tests/057-any.buzz @@ -3,18 +3,18 @@ import "std"; test "any" { any anything = "hello"; - assert(anything is str, message: "can manipulate any typed value"); + std.assert(anything is str, message: "can manipulate any typed value"); if (anything as str astring) { - assert(astring.len() == "hello".len(), message: "could cast any"); + std.assert(astring.len() == "hello".len(), message: "could cast any"); } } test "any placeholder" { - assert(placeholder is str, message: "can manipulate placeholder with any typed value"); + std.assert(placeholder is str, message: "can manipulate placeholder with any typed value"); if (placeholder as str astring) { - assert(astring.len() == "hello".len(), message: "could cast placeholder any"); + std.assert(astring.len() == "hello".len(), message: "could cast placeholder any"); } } @@ -23,16 +23,16 @@ any placeholder = "hello"; test "as?" { any anything = 12; - assert((anything as? int) == 12, message: "as?"); + std.assert((anything as? int) == 12, message: "as?"); - assert((anything as? str) == null, message: "as?"); + std.assert((anything as? str) == null, message: "as?"); } test "list of any" { [any] list = [ 1, true, 12.4, "hello" ]; foreach (any element in list) { - print("{element}"); + std.print("{element}"); } } @@ -43,7 +43,7 @@ test "map of any" { }; foreach (str key, any element in map) { - print("{key}: {element}"); + std.print("{key}: {element}"); } {any: str} map2 = { @@ -52,7 +52,7 @@ test "map of any" { }; foreach (any key, str element in map2) { - print("{key}: {element}"); + std.print("{key}: {element}"); } {any: any} map3 = { @@ -61,6 +61,6 @@ test "map of any" { }; foreach (any key, any element in map3) { - print("{key}: {element}"); + std.print("{key}: {element}"); } } \ No newline at end of file diff --git a/tests/058-ffi.buzz b/tests/058-ffi.buzz index 68c502b1..0e1c435b 100644 --- a/tests/058-ffi.buzz +++ b/tests/058-ffi.buzz @@ -1,5 +1,5 @@ import "std"; -import "buffer"; +import "buffer" as _; import "debug"; import "ffi"; @@ -12,16 +12,16 @@ zdef("tests/utils/libforeign", ` `); test "scalar type" { - assert(acos(0.12) == 1.4505064444001086, message: "Could call FFI function with scalar arguments"); + std.assert(acos(0.12) == 1.4505064444001086, message: "Could call FFI function with scalar arguments"); } test "cstring" { - fprint(cstr("hello world")); + fprint(ffi.cstr("hello world")); } test "pointer with Buffer" { | TODO: would be better with object destructor so the buffer can be collected - Buffer buffer = Buffer.init(); + var buffer = Buffer.init(); buffer.writeZ::("i32", values: [1, 2, 3]); buffer.writeZ::("i32", values: [1, 2, 3]); @@ -31,17 +31,17 @@ test "pointer with Buffer" { | But: that would require a new type | Since we cache the result of the type parsing this roughly equivalent buffer.writeZ::("u64", values: [1]); - assert(false, message: "Using bad buzz type triggers error"); - } catch (FFITypeMismatchError _) { - assert(true, message: "Using bad buzz type triggers error"); + std.assert(false, message: "Using bad buzz type triggers error"); + } catch (ffi.FFITypeMismatchError _) { + std.assert(true, message: "Using bad buzz type triggers error"); } - int i32align = alignOf("i32"); + int i32align = ffi.alignOf("i32"); int len = buffer.len(align: i32align); - assert(len == buffer.len() / 4, message: "Len align"); + std.assert(len == buffer.len() / 4, message: "Len align"); int total = sum(buffer.ptr(), len: len); - assert(total == 12, message: "Could call FFI function with pointer argument"); + std.assert(total == 12, message: "Could call FFI function with pointer argument"); int readTotal = 0; foreach (int i in 0..buffer.len(align: i32align)) { @@ -51,11 +51,11 @@ test "pointer with Buffer" { ); } - assert(readTotal == total, message: "Could read from pointer"); + std.assert(readTotal == total, message: "Could read from pointer"); int subTotal = sum(buffer.ptr(1, align: i32align), len: len - 1); - assert(subTotal == 11, message: "Could get ptr at offset"); + std.assert(subTotal == 11, message: "Could get ptr at offset"); } zdef("tests/utils/libforeign", ` @@ -71,41 +71,41 @@ zdef("tests/utils/libforeign", ` test "struct" { Data data = Data{ - msg = cstr("bye world"), + msg = ffi.cstr("bye world"), id = 123, value = 42.0, }; - assert(data.msg == "bye world\0", message: "Could instanciate Zig struct"); - assert(data.id == 123, message: "Could instanciate Zig struct"); + std.assert(data.msg == "bye world\0", message: "Could instanciate Zig struct"); + std.assert(data.id == 123, message: "Could instanciate Zig struct"); data.id = 42; - assert(data.id == 42, message: "Could set Zig struct field"); + std.assert(data.id == 42, message: "Could set Zig struct field"); - assert(get_data_msg(data) == "bye world\0", message: "Could use foreign function with struct ptr param"); + std.assert(get_data_msg(data) == "bye world\0", message: "Could use foreign function with struct ptr param"); set_data_id(data); - assert(data.id == 84, message: "Could use foreign function with struct ptr param that modifies the struct"); + std.assert(data.id == 84, message: "Could use foreign function with struct ptr param that modifies the struct"); } test "write/read struct in buffer" { Data data = Data{ - msg = cstr("bye world"), + msg = ffi.cstr("bye world"), id = 123, value = 42.0, }; - Buffer buffer = Buffer.init(); + var buffer = Buffer.init(); buffer.writeStruct::(Data, values: [data]); - assert(buffer.toString().len() == sizeOfStruct(Data), message: "Could write struct to buffer"); + std.assert(buffer.toString().len() == ffi.sizeOfStruct(Data), message: "Could write struct to buffer"); Data read = buffer.readStruct::(Data); - assert( + std.assert( read.msg == data.msg and read.id == data.id, message: "Could read struct from buffer" ); @@ -132,23 +132,23 @@ test "union" { Misc misc = Misc{ data = Data{ id = 123, - msg = cstr("hello world"), + msg = ffi.cstr("hello world"), value = 42.0, } }; - assert(get_misc_msg(misc) == cstr("hello world"), message: "Could read union field"); + std.assert(get_misc_msg(misc) == ffi.cstr("hello world"), message: "Could read union field"); misc.flag = Flag{ id = 123, value = true, }; - assert(get_misc_flag(misc), message: "Could read union field"); + std.assert(get_misc_flag(misc), message: "Could read union field"); misc.id = 321; - assert(misc.id == 321, message: "Got expected memory layout of a C union"); - assert(misc.data.id == 321, message: "Got expected memory layout of a C union"); - assert(misc.flag.id == 321, message: "Got expected memory layout of a C union"); + std.assert(misc.id == 321, message: "Got expected memory layout of a C union"); + std.assert(misc.data.id == 321, message: "Got expected memory layout of a C union"); + std.assert(misc.flag.id == 321, message: "Got expected memory layout of a C union"); } \ No newline at end of file diff --git a/tests/059-types-as-value.buzz b/tests/059-types-as-value.buzz index 0002237f..e06f2b73 100644 --- a/tests/059-types-as-value.buzz +++ b/tests/059-types-as-value.buzz @@ -7,7 +7,7 @@ enum B { } fun dumpType(type myType) > void { - print("{myType}"); + std.print("{myType}"); } protocol C {} @@ -17,19 +17,19 @@ test "Types as value" { type another = ; type again = ; - assert(another == again, message: "Can compare type values"); + std.assert(another == again, message: "Can compare type values"); } test "typeof" { - assert(typeof A{} == , message: "typeof operator instance"); - assert(typeof B.case == , message: "typeof operator case"); - assert(typeof "hello" == , message: "typeof operator str"); - assert(typeof true == , message: "typeof operator bool"); - assert(typeof null == , message: "typeof operator null"); - assert(typeof 1 == , message: "typeof operator int"); - assert(typeof 3.14 == , message: "typeof operator float"); - assert(typeof $"hello" == , message: "typeof operator pattern"); - assert(typeof dumpType == void *> void>, message: "typeof operator"); + std.assert(typeof A{} == , message: "typeof operator instance"); + std.assert(typeof B.case == , message: "typeof operator case"); + std.assert(typeof "hello" == , message: "typeof operator str"); + std.assert(typeof true == , message: "typeof operator bool"); + std.assert(typeof null == , message: "typeof operator null"); + std.assert(typeof 1 == , message: "typeof operator int"); + std.assert(typeof 3.14 == , message: "typeof operator float"); + std.assert(typeof $"hello" == , message: "typeof operator pattern"); + std.assert(typeof dumpType == void *> void>, message: "typeof operator"); } test "type argument" { @@ -44,10 +44,10 @@ zdef("tests/utils/libforeign", ` `); test "necessary weirdness" { - assert(() == typeof A{}, message: "typeof Object == typeof Object instance"); + std.assert(() == typeof A{}, message: "typeof Object == typeof Object instance"); - assert(typeof C == , message: "protocol is a type at runtime"); - assert(typeof Data == , message: "fstruct is a type at runtime"); + std.assert(typeof C == , message: "protocol is a type at runtime"); + std.assert(typeof Data == , message: "fstruct is a type at runtime"); } fun generic::(T value) > T { @@ -55,11 +55,11 @@ fun generic::(T value) > T { } fun typeArg(type T, str value) > str { - dump(T); + debug.dump(T); return value; } test "generic type expression ambiguity" { - dump(generic::("hello")); - dump(typeArg(, value: "hello")); + debug.dump(generic::("hello")); + debug.dump(typeArg(, value: "hello")); } \ No newline at end of file diff --git a/tests/060-free-identifiers.buzz b/tests/060-free-identifiers.buzz index 34c58f90..55ac1f25 100644 --- a/tests/060-free-identifiers.buzz +++ b/tests/060-free-identifiers.buzz @@ -3,7 +3,7 @@ import "std"; test "Free identifiers" { str @"non-standard-identifier" = "hello world"; - assert(@"non-standard-identifier" == "hello world", message: "Could use non-standard identifiers"); + std.assert(@"non-standard-identifier" == "hello world", message: "Could use non-standard identifiers"); } object A { @@ -15,5 +15,5 @@ test "Free identifier as object field" { @"type" = "Hello", }; - assert(a.@"type" == "Hello", message: "Could use non-standard identifiers as object field"); + std.assert(a.@"type" == "Hello", message: "Could use non-standard identifiers as object field"); } \ No newline at end of file diff --git a/tests/061-utf8.buzz b/tests/061-utf8.buzz index 60d52193..b314568f 100644 --- a/tests/061-utf8.buzz +++ b/tests/061-utf8.buzz @@ -3,13 +3,13 @@ import "std"; test "utf8" { str msg = "hello 🔥 buzz !"; - assert(msg.utf8Len() == 14, message: "Could get length of utf8 string"); - assert(msg.utf8Valid(), message: "Could validate utf8 string"); + std.assert(msg.utf8Len() == 14, message: "Could get length of utf8 string"); + std.assert(msg.utf8Valid(), message: "Could validate utf8 string"); str invalid = "hello \232 world!"; - assert(!invalid.utf8Valid(), message: "Could not validate invalid utf8 string"); + std.assert(!invalid.utf8Valid(), message: "Could not validate invalid utf8 string"); [str] codepoints = "I'm 🦇-man so 🔥 !".utf8Codepoints(); - assert(codepoints[4] == "🦇", message: "Could get utf8 string codepoints"); + std.assert(codepoints[4] == "🦇", message: "Could get utf8 string codepoints"); } \ No newline at end of file diff --git a/tests/063-nullable-default.buzz b/tests/063-nullable-default.buzz index 939ea70e..5bcfe781 100644 --- a/tests/063-nullable-default.buzz +++ b/tests/063-nullable-default.buzz @@ -10,11 +10,11 @@ test "Nullable object field has a default value at null" { name = "Joe" }; - assert(person.age == null, message: "Nullable object field has a default value at null"); + std.assert(person.age == null, message: "Nullable object field has a default value at null"); } test "Nullable variable has a default value at null" { str? hello; - assert(hello == null, message: "Nullable variable has default value at null"); + std.assert(hello == null, message: "Nullable variable has default value at null"); } \ No newline at end of file diff --git a/tests/064-throw-inside-try.buzz b/tests/064-throw-inside-try.buzz index a2632502..2139acfe 100644 --- a/tests/064-throw-inside-try.buzz +++ b/tests/064-throw-inside-try.buzz @@ -14,9 +14,9 @@ fun run() > void { throw SomeError{}; } catch (str _) { - assert(false, message: "Could throw inside try/catch"); + std.assert(false, message: "Could throw inside try/catch"); } catch (SomeError _) { - assert(true, message: "Could throw inside try/catch"); + std.assert(true, message: "Could throw inside try/catch"); } } diff --git a/tests/065-inferred-var-type.buzz b/tests/065-inferred-var-type.buzz index 1ee43df7..ad712f1b 100644 --- a/tests/065-inferred-var-type.buzz +++ b/tests/065-inferred-var-type.buzz @@ -8,14 +8,14 @@ var integer = 42; const floating = 42.42; test "Inferring variable declaration type" { - assert(integer is int, message: "Could infer global variable declaration type"); - assert(floating is float, message: "Could infer global constant declaration type"); + std.assert(integer is int, message: "Could infer global variable declaration type"); + std.assert(floating is float, message: "Could infer global constant declaration type"); var string = "hello"; - assert(string is str, message: "Could infer variable declaration type"); + std.assert(string is str, message: "Could infer variable declaration type"); const person = Person{}; - assert(person is Person, message: "Could infer constant declaration type"); + std.assert(person is Person, message: "Could infer constant declaration type"); } \ No newline at end of file diff --git a/tests/066-object-generics.buzz b/tests/066-object-generics.buzz index fbe824ff..209e5f43 100644 --- a/tests/066-object-generics.buzz +++ b/tests/066-object-generics.buzz @@ -14,6 +14,6 @@ test "Objects generics" { payload.data["two"] = 2; - assert(payload is Payload::, message: "Could use objects generics"); - assert(payload.data["two"] == 2, message: "Could use objects generics"); + std.assert(payload is Payload::, message: "Could use objects generics"); + std.assert(payload.data["two"] == 2, message: "Could use objects generics"); } \ No newline at end of file diff --git a/tests/068-testing.buzz b/tests/068-testing.buzz index e5b4e0e7..e77feda2 100644 --- a/tests/068-testing.buzz +++ b/tests/068-testing.buzz @@ -1,6 +1,4 @@ -import "std"; -import "test"; -import "os"; +import "testing" as _; test "Test std lib" { Tester t = Tester.init( diff --git a/tests/069-named-expr.buzz b/tests/069-named-expr.buzz index 0a45386e..f6795702 100644 --- a/tests/069-named-expr.buzz +++ b/tests/069-named-expr.buzz @@ -17,7 +17,7 @@ test "Named expr object properties" { sex = true, }; - assert( + std.assert( person.name == "joe" and person.age == 24 and person.sex, @@ -39,7 +39,7 @@ test "Name expr function argument" { var person = hello(name, age, sex: true); - assert( + std.assert( person.name == "joe" and person.age == 24 and person.sex, diff --git a/tests/070-block-expression.buzz b/tests/070-block-expression.buzz index 00052073..c76554e5 100644 --- a/tests/070-block-expression.buzz +++ b/tests/070-block-expression.buzz @@ -2,11 +2,11 @@ import "std"; test "block expression" { var value = from { - print("doing stuff in my block..."); + std.print("doing stuff in my block..."); out "my value"; }; - assert(value == "my value", message: "Could use block expression"); - assert(value is str, message: "Could infer block expression type properly"); + std.assert(value == "my value", message: "Could use block expression"); + std.assert(value is str, message: "Could infer block expression type properly"); } \ No newline at end of file diff --git a/tests/071-tail-call.buzz b/tests/071-tail-call.buzz index 67719a60..3de83867 100644 --- a/tests/071-tail-call.buzz +++ b/tests/071-tail-call.buzz @@ -9,7 +9,7 @@ fun tail(int a, int b) > int { } test "simple tail call" { - assert(tail(a: 5, b: 2) == 10); + std.assert(tail(a: 5, b: 2) == 10); } fun recursive(int limit, int current) > int { @@ -21,7 +21,7 @@ fun recursive(int limit, int current) > int { } test "recursive tail call" { - assert(recursive(limit: 5, current: 0) == 6); + std.assert(recursive(limit: 5, current: 0) == 6); } object Tail { @@ -43,5 +43,5 @@ test "dot tail call" { b = 2, }.tail(3); - print("{result}"); + std.print("{result}"); } \ No newline at end of file diff --git a/tests/bench/001-btree.buzz b/tests/bench/001-btree.buzz index f9ff1de2..55031335 100644 --- a/tests/bench/001-btree.buzz +++ b/tests/bench/001-btree.buzz @@ -1,6 +1,5 @@ import "std"; -import "math" as math; -import "errors"; +import "math"; object Node { Node? left = null, @@ -9,11 +8,9 @@ object Node { fun bottomUpTree(int depth) > Node { if (depth > 0) { - depth = depth - 1; - return Node{ - left = bottomUpTree(depth), - right = bottomUpTree(depth), + left = bottomUpTree(depth - 1), + right = bottomUpTree(depth - 1), }; } @@ -40,24 +37,24 @@ fun btree(int N) > void { int stretchdepth = maxdepth + 1; Node stretchtree = bottomUpTree(stretchdepth); - print("stretch tree of depth {stretchdepth},\t check: {itemCheck(stretchtree)}"); + std.print("stretch tree of depth {stretchdepth},\t check: {itemCheck(stretchtree)}"); Node longlivedtree = bottomUpTree(maxdepth); for (int depth = mindepth; depth < maxdepth; depth = depth + 2) { - int iterations = toInt(math.pow(x: 2.0, y: toFloat(maxdepth - depth + mindepth)) catch 0.0); + int iterations = std.toInt(math.pow(x: 2.0, y: std.toFloat(maxdepth - depth + mindepth)) catch 0.0); int check = 0; for (int i = 0; i < iterations; i = i + 1) { check = check + itemCheck(bottomUpTree(depth)); } - print("{iterations}\t trees of depth {depth}\t check: {check}"); + std.print("{iterations}\t trees of depth {depth}\t check: {check}"); } - print("long lived tree of depth {maxdepth}\t check: {itemCheck(longlivedtree)}"); + std.print("long lived tree of depth {maxdepth}\t check: {itemCheck(longlivedtree)}"); } fun main([str] args) > void !> any { - int N = if (args.len() > 0) parseInt(args[0]) ?? 3 else 3; + int N = if (args.len() > 0) std.parseInt(args[0]) ?? 3 else 3; btree(N); } \ No newline at end of file diff --git a/tests/bench/002-merkle.buzz b/tests/bench/002-merkle.buzz index 71a99ef7..16836fe6 100644 --- a/tests/bench/002-merkle.buzz +++ b/tests/bench/002-merkle.buzz @@ -1,5 +1,5 @@ import "std"; -import "math" as math; +import "math"; import "errors"; object Node { @@ -11,11 +11,9 @@ object Node { fun makeTree(int depth) > Node { if (depth > 0) { - depth = depth - 1; - return Node{ - left = makeTree(depth), - right = makeTree(depth), + left = makeTree(depth - 1), + right = makeTree(depth - 1), }; } @@ -25,7 +23,7 @@ fun makeTree(int depth) > Node { } fun check(Node tree) > bool { - if (tree.hash -> hash) { + if (tree.hash != null) { if (tree.value != null) { return true; } else { @@ -52,7 +50,7 @@ fun calHash(Node tree) > void { fun main([str] args) > void !> any { int N = 6; if (args.len() > 0) { - N = parseInt(args[0]) ?? 6; + N = std.parseInt(args[0]) ?? 6; } int mindepth = 4; @@ -65,11 +63,11 @@ fun main([str] args) > void !> any { Node stretchtree = makeTree(stretchdepth); calHash(stretchtree); - print("stretch tree of depth {stretchdepth}\t root hash: {stretchtree.hash ?? 0} check: {check(stretchtree)}"); + std.print("stretch tree of depth {stretchdepth}\t root hash: {stretchtree.hash ?? 0} check: {check(stretchtree)}"); Node longlivedtree = makeTree(maxdepth); for (int depth = mindepth; depth < maxdepth; depth = depth + 2) { - int iterations = toInt(math.pow(x: 2.0, y: toFloat(maxdepth - depth + mindepth))); + int iterations = std.toInt(math.pow(x: 2.0, y: std.toFloat(maxdepth - depth + mindepth))); int sum = 0; for (int i = 0; i < iterations; i = i + 1) { Node t = makeTree(depth); @@ -77,9 +75,9 @@ fun main([str] args) > void !> any { sum = sum + t.hash ?? 0; } - print("{iterations}\t trees of depth {depth}\t root hash sum: {sum}"); + std.print("{iterations}\t trees of depth {depth}\t root hash sum: {sum}"); } calHash(longlivedtree); - print("long lived tree of depth {maxdepth}\t root hash: {longlivedtree.hash ?? 0} check: {check(longlivedtree)}"); + std.print("long lived tree of depth {maxdepth}\t root hash: {longlivedtree.hash ?? 0} check: {check(longlivedtree)}"); } \ No newline at end of file diff --git a/tests/bench/003-nbody.buzz b/tests/bench/003-nbody.buzz index 07b8765b..be968d6f 100644 --- a/tests/bench/003-nbody.buzz +++ b/tests/bench/003-nbody.buzz @@ -1,5 +1,5 @@ import "std"; -import "math" as math; +import "math"; const float pi = 3.141592653589793; const float solarMass = 4.0 * pi * pi; @@ -150,16 +150,16 @@ fun main([str] args) > void { int N = 1000; if (args.len() > 0) { - N = parseInt(args[0]) ?? 1000; + N = std.parseInt(args[0]) ?? 1000; } int nbody = bodies.len(); offsetMomentum(bodies, nbody: nbody); - print("{energy(bodies, nbody: nbody)}"); + std.print("{energy(bodies, nbody: nbody)}"); for (int i = 0; i < N; i = i + 1) { advance(bodies, nbody: nbody, dt: 0.01); } - print("{energy(bodies, nbody: nbody)}"); + std.print("{energy(bodies, nbody: nbody)}"); } \ No newline at end of file diff --git a/tests/bench/004-spectral.buzz b/tests/bench/004-spectral.buzz index 468ab670..07694b77 100644 --- a/tests/bench/004-spectral.buzz +++ b/tests/bench/004-spectral.buzz @@ -1,5 +1,5 @@ import "std"; -import "math" as math; +import "math"; fun A(float i, float j) > float { float ij = i + j - 1.0; @@ -10,9 +10,9 @@ fun Av([float] x, [float] y, int N) > void { for (float i = 0.0; i < N; i = i + 1.0) { float a = 0.0; for (float j = 0.0; j < N; j = j + 1.0) { - a = a + x[toInt(j)] * A(i: i, j: j); + a = a + x[std.toInt(j)] * A(i: i, j: j); } - y[toInt(i)] = a; + y[std.toInt(i)] = a; } } @@ -20,9 +20,9 @@ fun Atv([float] x, [float] y, int N) > void { for (float i = 0.0; i < N; i = i + 1.0) { float a = 0.0; for (float j = 0.0; j < N; j = j + 1.0) { - a = a + x[toInt(j)] * A(i: j, j: i); + a = a + x[std.toInt(j)] * A(i: j, j: i); } - y[toInt(i)] = a; + y[std.toInt(i)] = a; } } @@ -34,7 +34,7 @@ fun AtAv([float] x, [float] y, [float] t, int N) > void { fun main([str] args) > void { int N = 100; if (args.len() > 0) { - N = parseInt(args[0]) ?? 100; + N = std.parseInt(args[0]) ?? 100; } [float] u = []; @@ -60,5 +60,5 @@ fun main([str] args) > void { vv = vv + vi * vi; } - print("{math.sqrt(vBv / vv)}"); + std.print("{math.sqrt(vBv / vv)}"); } \ No newline at end of file diff --git a/tests/bench/005-k-nucleoide.buzz b/tests/bench/005-k-nucleoide.buzz index f97115b9..842465fe 100644 --- a/tests/bench/005-k-nucleoide.buzz +++ b/tests/bench/005-k-nucleoide.buzz @@ -1,8 +1,8 @@ import "std"; -import "io" as io; +import "io"; import "errors"; -fun readSequence() > str !> ReadWriteError, FileSystemError, UnexpectedError { +fun readSequence() > str !> errors.ReadWriteError, errors.FileSystemError, errors.UnexpectedError { bool skippedIgnoredSequences = false; [str] lines = []; for (str? line = ""; line != null; line = io.stdin.readLine()) { | catch null doesn't work @@ -36,7 +36,7 @@ fun count(str sequence, str fragment) > void { for (int frame = 0; frame < k; frame = frame + 1) { kfrequency(sequence, frequency: frequency, k: k, frame: frame); } - print("{frequency[fragment] ?? 0}\t{fragment}"); + std.print("{frequency[fragment] ?? 0}\t{fragment}"); } fun frequency(str sequence, int k) > void { @@ -47,13 +47,13 @@ fun frequency(str sequence, int k) > void { int sum = sequence.len() - k + 1; foreach (str c, int f in frequency) { - print("{c} {(f * 100) / sum}"); + std.print("{c} {(f * 100) / sum}"); } - print(""); + std.print(""); } | buzz tests/bench/005-k-nucleoide.buzz < tests/bench/reference/knucleotide-input.txt -fun main([str] args) > void { +fun main([str] _) > void { str sequence = readSequence() catch ""; frequency(sequence, k: 1); frequency(sequence, k: 2); diff --git a/tests/bench/006-fasta.buzz b/tests/bench/006-fasta.buzz index 85d262bb..2b0990ce 100644 --- a/tests/bench/006-fasta.buzz +++ b/tests/bench/006-fasta.buzz @@ -1,6 +1,6 @@ import "std"; import "math"; -import "buffer"; +import "buffer" as _; const float IM = 139968.0; const float IA = 3877.0; @@ -9,12 +9,12 @@ const int lineLength = 60; const int bufferSize = (lineLength + 1) * 1024; fun makeRepeatFasta(str id, str desc, str s, int nchars) > void { - print(">{id} {desc}"); + std.print(">{id} {desc}"); int p = 0; int sn = s.len(); str s2 = s + s; for (int i = lineLength; i < nchars; i = i + lineLength) { - print(s2.sub(p, len: lineLength - 1)); + std.print(s2.sub(p, len: lineLength - 1)); p = p + lineLength; if (p > sn) { p = p - sn; @@ -22,7 +22,7 @@ fun makeRepeatFasta(str id, str desc, str s, int nchars) > void { } int tail = nchars % lineLength; if (tail > 0) { - print(s2.sub(p, len: tail - 1)); + std.print(s2.sub(p, len: tail - 1)); } } @@ -56,8 +56,9 @@ object Frequency { } } - fun selectRandomIntoBuffer(Buffer buffer, int bufferIndex, int nRandom) > int !> OutOfBoundError, WriteWhileReadingError { + fun selectRandomIntoBuffer(Buffer buffer, int initialBufferIndex, int nRandom) > int !> OutOfBoundError, WriteWhileReadingError { const int len = this.probs.len(); + var bufferIndex = initialBufferIndex; for (int rIndex = 0; rIndex < nRandom; rIndex = rIndex + 1) { float r = this.random(1.0); @@ -81,28 +82,29 @@ object Frequency { } } -fun makeRandomFasta(str id, str desc, Frequency fpf, int nchars) > void !> OutOfBoundError, WriteWhileReadingError { - print(">{id} {desc}"); +fun makeRandomFasta(str id, str desc, Frequency fpf, int initialNchars) > void !> OutOfBoundError, WriteWhileReadingError { + std.print(">{id} {desc}"); + var nchars = initialNchars; Buffer buffer = Buffer.init(bufferSize); int bufferIndex = 0; while (nchars > 0) { - int chunkSize = toInt(minFloat(a: toFloat(lineLength), b: toFloat(nchars))); + int chunkSize = std.toInt(math.minFloat(a: std.toFloat(lineLength), b: std.toFloat(nchars))); if (bufferIndex == bufferSize) { - print(buffer.toString().sub(0, len: bufferIndex)); + std.print(buffer.toString().sub(0, len: bufferIndex)); buffer = Buffer.init(bufferSize); bufferIndex = 0; } - bufferIndex = fpf.selectRandomIntoBuffer(buffer, bufferIndex: bufferIndex, nRandom: chunkSize); + bufferIndex = fpf.selectRandomIntoBuffer(buffer, initialBufferIndex: bufferIndex, nRandom: chunkSize); buffer.setAt(bufferIndex, value: 10); bufferIndex = bufferIndex + 1; nchars = nchars - chunkSize; } - print(buffer.toString().sub(0, len: bufferIndex)); + std.print(buffer.toString().sub(0, len: bufferIndex)); } const str alu = "GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGG" @@ -116,7 +118,7 @@ const str alu = "GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGG" fun main([str] args) > void !> any { int N = 1000; if (args.len() > 0) { - N = parseInt(args[0]) ?? 1000; + N = std.parseInt(args[0]) ?? 1000; } makeRepeatFasta("ONE", desc: "Homo sapiens alu", s: alu, nchars: N * 2); @@ -129,7 +131,7 @@ fun main([str] args) > void !> any { last: 42.0, ); - makeRandomFasta("TWO", desc: "IUB ambiguity codes", fpf: iub, nchars: N * 3); + makeRandomFasta("TWO", desc: "IUB ambiguity codes", fpf: iub, initialNchars: N * 3); Buffer homoSapiensChars = Buffer.init(); homoSapiensChars.write("acgt"); @@ -139,5 +141,5 @@ fun main([str] args) > void !> any { last: iub.last, ); - makeRandomFasta("THREE", desc: "Homo sapiens frequency", fpf: homoSapiens, nchars: N * 5); + makeRandomFasta("THREE", desc: "Homo sapiens frequency", fpf: homoSapiens, initialNchars: N * 5); } \ No newline at end of file diff --git a/tests/bench/007-fib.buzz b/tests/bench/007-fib.buzz index b4a50f97..ef18f333 100644 --- a/tests/bench/007-fib.buzz +++ b/tests/bench/007-fib.buzz @@ -9,5 +9,5 @@ fun fibonnacci(int n) > int { } fun main([str] _) > void { - print("{fibonnacci(30)}"); + std.print("{fibonnacci(30)}"); } \ No newline at end of file diff --git a/tests/bench/008-for.buzz b/tests/bench/008-for.buzz index 7f7a088e..950196f5 100644 --- a/tests/bench/008-for.buzz +++ b/tests/bench/008-for.buzz @@ -1,6 +1,6 @@ import "std"; -fun main([str] args) > void { +fun main([str] _) > void { [int] list = []; for (int i = 0; i < 1000000; i = i + 1) { @@ -8,9 +8,9 @@ fun main([str] args) > void { } int sum = 0; - foreach (int i, int v in list) { + foreach (int v in list) { sum = sum + v; } - print("{sum}"); + std.print("{sum}"); } \ No newline at end of file diff --git a/tests/bench/009-grid.buzz b/tests/bench/009-grid.buzz index 83861239..7a624f66 100644 --- a/tests/bench/009-grid.buzz +++ b/tests/bench/009-grid.buzz @@ -1,13 +1,13 @@ import "std"; fun main([str] args) > void { - const int width = (if (args.len() > 0) parseInt(args[0]) else 80) ?? 80; - const int height = (if (args.len() > 1) parseInt(args[1]) else 60) ?? 60; + const int width = (if (args.len() > 0) std.parseInt(args[0]) else 80) ?? 80; + const int height = (if (args.len() > 1) std.parseInt(args[1]) else 60) ?? 60; var cells = []; for (int i = 0; i < width * height; i = i + 1) { - cells.append(random(max: 5) == 1); + cells.append(std.random(max: 5) == 1); } for (int y = 0; y < height; y = y + 1) { diff --git a/tests/bench/010-ackermann.buzz b/tests/bench/010-ackermann.buzz index a010b1e0..dce54d10 100644 --- a/tests/bench/010-ackermann.buzz +++ b/tests/bench/010-ackermann.buzz @@ -1,10 +1,10 @@ import "std"; fun main([str] args) > void { - const m = (if (args.len() > 0) parseInt(args[0]) else null) ?? 3; - const n = (if (args.len() > 1) parseInt(args[1]) else null) ?? 8; + const m = (if (args.len() > 0) std.parseInt(args[0]) else null) ?? 3; + const n = (if (args.len() > 1) std.parseInt(args[1]) else null) ?? 8; - print("result: {ack(m, n)}"); + std.print("result: {ack(m, n)}"); } fun ack(int m, int n) > int { diff --git a/tests/bench/011-bubble-sort.buzz b/tests/bench/011-bubble-sort.buzz index 220f83cb..f2dd146a 100644 --- a/tests/bench/011-bubble-sort.buzz +++ b/tests/bench/011-bubble-sort.buzz @@ -1,14 +1,14 @@ import "std"; fun main([str] args) > void { - const max = (if (args.len() > 0) parseInt(args[0]) else null) ?? 750; + const max = (if (args.len() > 0) std.parseInt(args[0]) else null) ?? 750; var list = init(max); bubblesort(list); foreach (int e in list) { - print("{e}"); + std.print("{e}"); } } diff --git a/tests/compile_errors/006-deep-yield.buzz b/tests/compile_errors/006-deep-yield.buzz index 5cfffea6..a0960101 100644 --- a/tests/compile_errors/006-deep-yield.buzz +++ b/tests/compile_errors/006-deep-yield.buzz @@ -11,5 +11,5 @@ fun two() > void { test "Deep yield" { fib fiber = &two(); - print(resume fiber ?? "nope"); + std.print(resume fiber ?? "nope"); } \ No newline at end of file diff --git a/tests/compile_errors/010-multiple-location.buzz b/tests/compile_errors/010-multiple-location.buzz index fe66d8e6..a6d439a8 100644 --- a/tests/compile_errors/010-multiple-location.buzz +++ b/tests/compile_errors/010-multiple-location.buzz @@ -6,7 +6,7 @@ object Some { } test "Badly initializing an object declared in another file" { - CompileError o = CompileError{ + var _ = errors.CompileError{ name = "wtf", }; } \ No newline at end of file diff --git a/tests/compile_errors/021-fiber-error-location.buzz b/tests/compile_errors/021-fiber-error-location.buzz index 3cd19ddc..c172c466 100644 --- a/tests/compile_errors/021-fiber-error-location.buzz +++ b/tests/compile_errors/021-fiber-error-location.buzz @@ -20,7 +20,7 @@ fun run() > void { sum = sum + resume counter ?? 0; } - print(resolve counter); + std.print(resolve counter); } test "fiber error location" { diff --git a/tests/compile_errors/027-early-return.buzz b/tests/compile_errors/027-early-return.buzz index d0a7877d..86c48f1a 100644 --- a/tests/compile_errors/027-early-return.buzz +++ b/tests/compile_errors/027-early-return.buzz @@ -2,9 +2,9 @@ import "std"; test "Early return" { - print("I sure hope i'm not interrupted..."); + std.print("I sure hope i'm not interrupted..."); return; - print("Guess I was"); + std.print("Guess I was"); } \ No newline at end of file diff --git a/tests/manual/001-cli-args.buzz b/tests/manual/001-cli-args.buzz index 9cea95b8..669ef2a9 100644 --- a/tests/manual/001-cli-args.buzz +++ b/tests/manual/001-cli-args.buzz @@ -2,6 +2,6 @@ import "std"; fun main([str] args) > void { foreach (int index, str arg in args) { - print("{index}: {arg}"); + std.print("{index}: {arg}"); } } \ No newline at end of file diff --git a/tests/manual/002-error.buzz b/tests/manual/002-error.buzz index 44d95a78..8cd17f75 100644 --- a/tests/manual/002-error.buzz +++ b/tests/manual/002-error.buzz @@ -1,3 +1,3 @@ -fun main([str] args) > void { +fun main([str] _) > void { throw "wat!"; } \ No newline at end of file diff --git a/tests/manual/003-io.buzz b/tests/manual/003-io.buzz index aa31b6f7..b60102bf 100644 --- a/tests/manual/003-io.buzz +++ b/tests/manual/003-io.buzz @@ -2,8 +2,8 @@ import "std"; import "io"; test "Read stdin" { - for (str? line = ""; line != null; line = stdin.readLine()) { - print("= {line}"); - stdout.write("> "); + for (str? line = ""; line != null; line = io.stdin.readLine()) { + std.print("= {line}"); + io.stdout.write("> "); } } \ No newline at end of file diff --git a/tests/manual/004-os.buzz b/tests/manual/004-os.buzz index 4562d140..252ca148 100644 --- a/tests/manual/004-os.buzz +++ b/tests/manual/004-os.buzz @@ -1,4 +1,4 @@ -import "os" as os; +import "os"; test "os.exit" { os.exit(12); diff --git a/tests/manual/005-tcp-client.buzz b/tests/manual/005-tcp-client.buzz index b1f03b13..e456e09f 100644 --- a/tests/manual/005-tcp-client.buzz +++ b/tests/manual/005-tcp-client.buzz @@ -2,13 +2,13 @@ import "std"; import "os"; test "Opening a socket" { - Socket socket = Socket.connect( + var socket = os.Socket.connect( address: "127.0.0.1", port: 8080, - netProtocol: SocketProtocol.tcp + netProtocol: os.SocketProtocol.tcp ); - print("socket fd: {socket.fd}"); + std.print("socket fd: {socket.fd}"); socket.send("hello world"); diff --git a/tests/manual/007-http-client.buzz b/tests/manual/006-http-client.buzz similarity index 58% rename from tests/manual/007-http-client.buzz rename to tests/manual/006-http-client.buzz index b11d03ad..df092f30 100644 --- a/tests/manual/007-http-client.buzz +++ b/tests/manual/006-http-client.buzz @@ -5,10 +5,10 @@ import "errors"; import "serialize"; fun main([str] _) > void !> any { - const client = Client.init(); + const client = http.Client.init(); - const request = Request{ - method = Method.GET, + const request = http.Request{ + method = http.Method.GET, headers = { "accept": "*/*", "user-agent": "buzz", @@ -17,7 +17,7 @@ fun main([str] _) > void !> any { }; const response = client.send(request); - const fact = jsonDecode(response.body ?? "null").q(["fact"]).stringValue(); + const fact = serialize.jsonDecode(response.body ?? "null").q(["fact"]).stringValue(); - dump(fact); + debug.dump(fact); } \ No newline at end of file diff --git a/tests/manual/006-tcp-server.buzz b/tests/manual/006-tcp-server.buzz deleted file mode 100644 index 0b3839da..00000000 --- a/tests/manual/006-tcp-server.buzz +++ /dev/null @@ -1,30 +0,0 @@ -import "std"; -import "os"; -import "http"; - -test "Opening a socket" { - TcpServer server = TcpServer.init( - address: "127.0.0.1", - port: 8080, - reuseAddr: true, - reusePort: true, - ); - - print("Listening on 127.0.0.1:8080..."); - - Socket socket = server.accept(); - - print("Accepted connection"); - - Request request = Request.parse(socket.receiveAll() ?? ""); - - print("Received request: {request.method} {request.url}"); - print("headers:"); - foreach (str key, str value in request.headers) { - print("{key}: {value}"); - } - print("body: `{request.body ?? ""}`"); - - socket.close(); - server.close(); -} \ No newline at end of file diff --git a/tests/utils/import-a.buzz b/tests/utils/import-a.buzz index 5f859bd9..ad92b2ee 100644 --- a/tests/utils/import-a.buzz +++ b/tests/utils/import-a.buzz @@ -1,3 +1,5 @@ +namespace a; + object Hello { str message, } diff --git a/tests/utils/import-b.buzz b/tests/utils/import-b.buzz index 0929337f..4bb7f966 100644 --- a/tests/utils/import-b.buzz +++ b/tests/utils/import-b.buzz @@ -1,10 +1,12 @@ +namespace b; + import "tests/utils/import-a"; import "std"; -Hello hello = Hello{ message = "hello world" }; +var hello = a.Hello{ message = "hello world" }; fun printClass() > void { - print("b: {Hello}"); + std.print("b: {a.Hello}"); } export hello; diff --git a/tests/utils/testing.buzz b/tests/utils/testing.buzz index 09d6721b..ffa7d89e 100644 --- a/tests/utils/testing.buzz +++ b/tests/utils/testing.buzz @@ -1,3 +1,5 @@ +namespace testing; + import "std" as std; int unexported = 42;