Skip to content

Commit

Permalink
feat(language): Arrow notation goes from -> to =>
Browse files Browse the repository at this point in the history
- It's more commonly expected
- `->` is already used when unwrapping nullable in a if statement
  • Loading branch information
giann committed Jul 21, 2024
1 parent 171795a commit 68454de
Show file tree
Hide file tree
Showing 17 changed files with 89 additions and 69 deletions.
4 changes: 3 additions & 1 deletion src/Codegen.zig
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,8 @@ pub fn identifierConstant(self: *Self, name: []const u8) !u24 {

// Unlocated error, should not be used
fn reportError(self: *Self, error_type: Reporter.Error, message: []const u8) void {
@setCold(true);

if (self.reporter.panic_mode) {
return;
}
Expand Down Expand Up @@ -388,7 +390,7 @@ fn endScope(self: *Self, node: Ast.Node.Index) Error!void {
}
}

inline fn generateNode(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj.ObjFunction {
fn generateNode(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj.ObjFunction {
if (self.synchronize(node)) {
return null;
}
Expand Down
20 changes: 12 additions & 8 deletions src/Parser.zig
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,7 @@ const rules = [_]ParseRule{
.{ .prefix = null, .infix = binary, .precedence = .Comparison }, // LessEqual
.{ .prefix = null, .infix = binary, .precedence = .NullCoalescing }, // QuestionQuestion
.{ .prefix = null, .infix = null, .precedence = .None }, // Arrow
.{ .prefix = null, .infix = null, .precedence = .None }, // DoubleArrow
.{ .prefix = literal, .infix = null, .precedence = .None }, // True
.{ .prefix = literal, .infix = null, .precedence = .None }, // False
.{ .prefix = literal, .infix = null, .precedence = .None }, // Null
Expand Down Expand Up @@ -530,23 +531,26 @@ pub fn deinit(self: *Self) void {
self.ffi.deinit();
}

inline fn reportErrorAtCurrent(self: *Self, error_type: Reporter.Error, message: []const u8) void {
fn reportErrorAtCurrent(self: *Self, error_type: Reporter.Error, message: []const u8) void {
@setCold(true);
self.reporter.reportErrorAt(
error_type,
self.ast.tokens.get(self.current_token.?),
message,
);
}

pub inline fn reportError(self: *Self, error_type: Reporter.Error, message: []const u8) void {
pub fn reportError(self: *Self, error_type: Reporter.Error, message: []const u8) void {
@setCold(true);
self.reporter.reportErrorAt(
error_type,
self.ast.tokens.get(if (self.current_token.? > 0) self.current_token.? - 1 else 0),
message,
);
}

inline fn reportErrorFmt(self: *Self, error_type: Reporter.Error, comptime fmt: []const u8, args: anytype) void {
fn reportErrorFmt(self: *Self, error_type: Reporter.Error, comptime fmt: []const u8, args: anytype) void {
@setCold(true);
self.reporter.reportErrorFmt(
error_type,
self.ast.tokens.get(if (self.current_token.? > 0) self.current_token.? - 1 else 0),
Expand Down Expand Up @@ -2241,7 +2245,7 @@ fn parseVariable(
);
}

inline fn markInitialized(self: *Self) void {
fn markInitialized(self: *Self) void {
if (self.current.?.scope_depth == 0) {
// assert(!self.globals.items[self.globals.items.len - 1].initialized);
self.globals.items[self.globals.items.len - 1].initialized = true;
Expand Down Expand Up @@ -4930,7 +4934,7 @@ fn inlineIf(self: *Self, _: bool) Error!Ast.Node.Index {
return try self.@"if"(false, null);
}

inline fn isAs(self: *Self, left: Ast.Node.Index, is_expr: bool) Error!Ast.Node.Index {
fn isAs(self: *Self, left: Ast.Node.Index, is_expr: bool) Error!Ast.Node.Index {
const start_location = self.ast.nodes.items(.location)[left];
const constant = try self.parseTypeDef(null, true);
const type_def = self.ast.nodes.items(.type_def)[constant].?;
Expand Down Expand Up @@ -5370,7 +5374,7 @@ fn function(

const end_token: Token.Type = if (function_type.canOmitBody()) .Semicolon else .LeftBrace;

while (!self.check(end_token) and !self.check(.Arrow) and !self.check(.Eof)) {
while (!self.check(end_token) and !self.check(.DoubleArrow) and !self.check(.Eof)) {
const error_type_node = try self.parseTypeDef(
self.ast.nodes.items(.type_def)[function_node].?.resolved_type.?.Function.generic_types,
true,
Expand All @@ -5384,7 +5388,7 @@ fn function(
self.reportError(.error_type, "Error type can't be optional");
}

if (!self.check(end_token) and !self.check(.Arrow)) {
if (!self.check(end_token) and !self.check(.DoubleArrow)) {
try self.consume(.Comma, "Expected `,` after error type");
}
}
Expand All @@ -5397,7 +5401,7 @@ fn function(
self.ast.nodes.items(.components)[function_signature].FunctionType.error_types = error_types.items;

// Parse body
if (try self.match(.Arrow)) {
if (try self.match(.DoubleArrow)) {
function_typedef.resolved_type.?.Function.lambda = true;
self.ast.nodes.items(.components)[function_signature].FunctionType.lambda = true;
const expr = try self.expression(false);
Expand Down
16 changes: 15 additions & 1 deletion src/Scanner.zig
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,20 @@ pub fn scanToken(self: *Self) !Token {
self.makeToken(.DoubleColon, null, null, null)
else
self.makeToken(.Colon, null, null, null),
'=' => self.makeToken(if (self.match('=')) .EqualEqual else .Equal, null, null, null),
'=' => if (self.match('>'))
self.makeToken(
.DoubleArrow,
null,
null,
null,
)
else
self.makeToken(
if (self.match('=')) .EqualEqual else .Equal,
null,
null,
null,
),
'"' => self.string(false),
'`' => self.string(true),
'\'' => self.byte(),
Expand Down Expand Up @@ -682,6 +695,7 @@ pub fn highlight(self: *Self, out: anytype, true_color: bool) void {
.Colon,
.DoubleColon,
.Arrow,
.DoubleArrow,
.Ampersand,
.Spread,
=> if (true_color) Color.punctuation else Color.bright_white,
Expand Down
1 change: 1 addition & 0 deletions src/Token.zig
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ pub const Type = enum {
LessEqual, // <=
QuestionQuestion, // ??
Arrow, // ->
DoubleArrow, // =>
True, // true
False, // false
Null, // null
Expand Down
1 change: 0 additions & 1 deletion src/builtin/list.zig
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
const builtin = @import("builtin");
const is_wasm = builtin.cpu.arch.isWasm();
const std = @import("std");
const _obj = @import("../obj.zig");
const ObjString = _obj.ObjString;
Expand Down
6 changes: 3 additions & 3 deletions src/lib/buzz_buffer.zig
Original file line number Diff line number Diff line change
Expand Up @@ -501,7 +501,7 @@ pub export fn BufferAt(ctx: *api.NativeCtx) c_int {
return 1;
}

inline fn rawWriteZ(
fn rawWriteZ(
ctx: *api.NativeCtx,
buffer: *Buffer,
ztype: []const u8,
Expand Down Expand Up @@ -584,7 +584,7 @@ pub export fn BufferWriteZAt(ctx: *api.NativeCtx) c_int {
)) -1 else 0;
}

inline fn rawWriteStruct(
fn rawWriteStruct(
vm: *api.VM,
buffer: *Buffer,
at: usize,
Expand Down Expand Up @@ -666,7 +666,7 @@ pub export fn BufferWriteStructAt(ctx: *api.NativeCtx) c_int {
)) -1 else 0;
}

inline fn rawReadStruct(
fn rawReadStruct(
vm: *api.VM,
buffer: *Buffer,
at: ?usize,
Expand Down
2 changes: 1 addition & 1 deletion src/lib/ffi.buzz
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace ffi;

export fun cstr(str string) -> "{string}\0";
export fun cstr(str string) => "{string}\0";

export object FFITypeMismatchError {
str message = "Provided buzz value type does not match expected FFI type",
Expand Down
12 changes: 6 additions & 6 deletions src/lib/serialize.buzz
Original file line number Diff line number Diff line change
Expand Up @@ -64,17 +64,17 @@ export object Boxed {
}

|| @return wrapped data string value or empty string if not a string
fun stringValue() > str -> this.string() ?? ""
fun stringValue() > str => this.string() ?? ""
|| @return wrapped data boolean value or `false` if not a boolean
fun booleanValue() > bool -> this.boolean() ?? false
fun booleanValue() > bool => this.boolean() ?? false
|| @return wrapped data number value or `0` if not an integer
fun integerValue() > int -> this.integer() ?? 0
fun integerValue() > int => this.integer() ?? 0
|| @return wrapped data number value or `0` if not a float
fun floatingValue() > float -> this.floating() ?? 0.0
fun floatingValue() > float => this.floating() ?? 0.0
|| @return wrapped data map value or empty map if not a map
fun mapValue() > {str: Boxed} -> this.map() ?? {<str: Boxed>}
fun mapValue() > {str: Boxed} => this.map() ?? {<str: Boxed>}
|| @return wrapped data list value or empty list if not a list
fun listValue() > [Boxed] -> this.list() ?? [<Boxed>]
fun listValue() > [Boxed] => this.list() ?? [<Boxed>]

|| Query the json element at `path`, if nothing matches return `Boxed{}`
|| @param path Path to query
Expand Down
50 changes: 25 additions & 25 deletions src/lib/testing.buzz
Original file line number Diff line number Diff line change
Expand Up @@ -38,28 +38,28 @@ export fun color(str text, Color color, bool reset = true) > str {
return "\27[{color.value}m{text}{if (reset) "\27[0m" else ""}";
}

export fun bright(str text) -> color(text, color: Color.bright);
export fun dim(str text) -> color(text, color: Color.dim);
export fun underscore(str text) -> color(text, color: Color.underscore);
export fun blink(str text) -> color(text, color: Color.blink);
export fun reverse(str text) -> color(text, color: Color.reverse);
export fun hidden(str text) -> color(text, color: Color.hidden);
export fun black(str text) -> color(text, color: Color.black);
export fun red(str text) -> color(text, color: Color.red);
export fun green(str text) -> color(text, color: Color.green);
export fun yellow(str text) -> color(text, color: Color.yellow);
export fun blue(str text) -> color(text, color: Color.blue);
export fun magenta(str text) -> color(text, color: Color.magenta);
export fun cyan(str text) -> color(text, color: Color.cyan);
export fun white(str text) -> color(text, color: Color.white);
export fun onblack(str text) -> color(text, color: Color.onblack);
export fun onred(str text) -> color(text, color: Color.onred);
export fun ongreen(str text) -> color(text, color: Color.ongreen);
export fun onyellow(str text) -> color(text, color: Color.onyellow);
export fun onblue(str text) -> color(text, color: Color.onblue);
export fun onmagenta(str text) -> color(text, color: Color.onmagenta);
export fun oncyan(str text) -> color(text, color: Color.oncyan);
export fun onwhite(str text) -> color(text, color: Color.onwhite);
export fun bright(str text) => color(text, color: Color.bright);
export fun dim(str text) => color(text, color: Color.dim);
export fun underscore(str text) => color(text, color: Color.underscore);
export fun blink(str text) => color(text, color: Color.blink);
export fun reverse(str text) => color(text, color: Color.reverse);
export fun hidden(str text) => color(text, color: Color.hidden);
export fun black(str text) => color(text, color: Color.black);
export fun red(str text) => color(text, color: Color.red);
export fun green(str text) => color(text, color: Color.green);
export fun yellow(str text) => color(text, color: Color.yellow);
export fun blue(str text) => color(text, color: Color.blue);
export fun magenta(str text) => color(text, color: Color.magenta);
export fun cyan(str text) => color(text, color: Color.cyan);
export fun white(str text) => color(text, color: Color.white);
export fun onblack(str text) => color(text, color: Color.onblack);
export fun onred(str text) => color(text, color: Color.onred);
export fun ongreen(str text) => color(text, color: Color.ongreen);
export fun onyellow(str text) => color(text, color: Color.onyellow);
export fun onblue(str text) => color(text, color: Color.onblue);
export fun onmagenta(str text) => color(text, color: Color.onmagenta);
export fun oncyan(str text) => color(text, color: Color.oncyan);
export fun onwhite(str text) => color(text, color: Color.onwhite);

export object Tester {
[bool] tests = [<bool>],
Expand Down Expand Up @@ -99,23 +99,23 @@ export object Tester {
fun failedAsserts() > int {
return this.asserts.reduce::<int>(
fun (int _, bool success, int accumulator)
-> accumulator + if (success) 0 else 1,
=> accumulator + if (success) 0 else 1,
initial: 0,
);
}

fun failedTests() > int {
return this.tests.reduce::<int>(
fun (int _, bool success, int accumulator)
-> accumulator + if (success) 0 else 1,
=> accumulator + if (success) 0 else 1,
initial: 0,
);
}

fun succeededTests() > int {
return this.tests.reduce::<int>(
fun (int _, bool success, int accumulator)
-> accumulator + if (success) 1 else 0,
=> accumulator + if (success) 1 else 0,
initial: 0,
);
}
Expand Down
4 changes: 2 additions & 2 deletions src/obj.zig
Original file line number Diff line number Diff line change
Expand Up @@ -62,15 +62,15 @@ pub const Obj = struct {
is_dirty: bool = false,
node: ?*std.DoublyLinkedList(*Obj).Node = null,

pub inline fn cast(obj: *Obj, comptime T: type, obj_type: ObjType) ?*T {
pub fn cast(obj: *Obj, comptime T: type, obj_type: ObjType) ?*T {
if (obj.obj_type != obj_type) {
return null;
}

return @alignCast(@fieldParentPtr("obj", obj));
}

pub inline fn access(obj: *Obj, comptime T: type, obj_type: ObjType, gc: *GarbageCollector) ?*T {
pub fn access(obj: *Obj, comptime T: type, obj_type: ObjType, gc: *GarbageCollector) ?*T {
if (BuildOptions.gc_debug_access) {
gc.debugger.?.accessed(obj, gc.where);
}
Expand Down
8 changes: 4 additions & 4 deletions tests/012-lambda.buzz
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import "std";

test "Lambda/Anonymous functions" {
Function(int n) > int mul = fun (int n) > int -> n * 2;
Function(int n) > int mul = fun (int n) > int => n * 2;

std.assert(mul(1) == 2, message: "called a lambda function");
}
Expand All @@ -12,11 +12,11 @@ fun callThis(Function(int n) > int fn, int arg) > int {

test "Function as arguments" {
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");
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;
fun mul(int a, int b) > int => a * b;

test "Any function can be an arrow function" {
std.assert(mul(a: 2, b: 2) == 4, message: "arrow function");
Expand Down
2 changes: 1 addition & 1 deletion tests/021-upvalues.buzz
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ fun upvals() > Function() {
int upvalue = 12;
str up = "up";

return fun () > void -> std.print("{upvalue} {up}");
return fun () > void => std.print("{upvalue} {up}");
}

test "Upvalues" {
Expand Down
2 changes: 1 addition & 1 deletion tests/029-default-arguments.buzz
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import "std";

fun hey(str name = "Joe", int age = 12, str? father, int fourth = 1) > str
-> "Hello {name} you're {age} {father} {fourth}";
=> "Hello {name} you're {age} {father} {fourth}";

test "function default arguments" {
std.assert(hey("John") == "Hello John you're 12 null 1", message: "Could reorder or omit argument");
Expand Down
2 changes: 1 addition & 1 deletion tests/032-debug.buzz
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import "debug";
| str source = debug.ast(`
| import \"std\";
|
| fun main([str] _) > void -> std.print(\"hello world\");
| fun main([str] _) > void => std.print(\"hello world\");
| `, scriptName: "test");
|
| Boxed jsonAST = jsonDecode(source);
Expand Down
6 changes: 3 additions & 3 deletions tests/038-fibers.buzz
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,13 @@ test "Throw inside a fiber" {
fun closedUpvalue() > Function() > str {
str upvalue = "joe";

return fun () > str -> "hello {upvalue}";
return fun () > str => "hello {upvalue}";
}

test "Opened upvalue in fiber" {
str upvalue = "world";

Function() > str fiberFn = fun () > str -> "hello {upvalue}";
Function() > str fiberFn = fun () > str => "hello {upvalue}";

std.assert(resolve &fiberFn() == "hello world", message: "Fiber could use an opened upvalue");
}
Expand All @@ -71,7 +71,7 @@ test "Closed upvalue in fiber" {

test "Wrapping call inside complex expressions" {
{str: Function() > str} map = {
"hello": fun () > str -> "hello world",
"hello": fun () > str => "hello world",
};

std.assert(resolve &map["hello"]?() == "hello world", message:"Could warp function call in a complex expression");
Expand Down
4 changes: 2 additions & 2 deletions tests/048-generics.buzz
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ test "Generic within anonymous object and map" {
}

fun countShuffleGenerics::<A, B>() > Function([A] a, [B] b) > int {
return fun ([A] a, [B] b) > int -> a.len() + b.len();
return fun ([A] a, [B] b) > int => a.len() + b.len();
}

test "Generic in lambda function definition" {
Expand Down Expand Up @@ -101,7 +101,7 @@ fun doubleGeneric::<A, B>(Function::<C, D>() > int lambda) > int {
test "Generic with generic lambda parameter" {
std.assert(
doubleGeneric::<str, int>(
fun::<E, F>() > int -> 12
fun::<E, F>() > int => 12
) == 12,
message: "could defined multiple generics"
);
Expand Down
Loading

0 comments on commit 68454de

Please sign in to comment.