From 13b8c359bd520508a05e4a0c4279668c084aae35 Mon Sep 17 00:00:00 2001 From: Rynco Maekawa Date: Mon, 9 Sep 2024 10:42:14 +0800 Subject: [PATCH] Update language definition and runtime --- MiniMoonBit.g4 | 38 ++++++------- riscv_rt/src/lib.zig | 125 +++++++++++++++++++++++++++---------------- 2 files changed, 95 insertions(+), 68 deletions(-) diff --git a/MiniMoonBit.g4 b/MiniMoonBit.g4 index 5976a82..e101ba5 100644 --- a/MiniMoonBit.g4 +++ b/MiniMoonBit.g4 @@ -46,40 +46,35 @@ let_stmt: 'let' IDENTIFIER type_annotation? '=' expr ';' stmt; type_annotation: COLON type; -fn_decl_stmt: top_fn_decl ';' stmt; +fn_decl_stmt: nontop_fn_decl ';' stmt; assign_stmt: get_expr '=' expr ';' stmt; // x[y] = z; expr_stmt: expr; // Expressions, in order of precedence. -expr: - add_sub_level_expr - | add_sub_level_expr '==' expr - | add_sub_level_expr '<=' expr; +expr: // not associative + | add_sub_level_expr '==' add_sub_level_expr + | add_sub_level_expr '<=' add_sub_level_expr + | add_sub_level_expr; -add_sub_level_expr: - mul_div_level_expr - | mul_div_level_expr '+' add_sub_level_expr - | mul_div_level_expr '-' add_sub_level_expr; +add_sub_level_expr: // left associative + | add_sub_level_expr '+' mul_div_level_expr + | add_sub_level_expr '-' mul_div_level_expr + | mul_div_level_expr; -mul_div_level_expr: - if_level_expr - | if_level_expr '*' mul_div_level_expr - | if_level_expr '/' mul_div_level_expr; +mul_div_level_expr: // left associative + | mul_div_level_expr '*' if_level_expr + | mul_div_level_expr '/' if_level_expr + | if_level_expr; if_level_expr: get_or_apply_level_expr | if_expr; if_expr: 'if' expr block_expr ('else' block_expr)?; get_or_apply_level_expr: - get_expr - | apply_expr - | value_expr; -get_expr: value_expr '[' expr ']'; // x[y] -apply_expr: empty_apply_expr | nonempty_apply_expr; -empty_apply_expr: value_expr '(' ')'; // f() -nonempty_apply_expr: - value_expr '(' expr (',' expr)* ')'; // f(x, y) + | value_expr + | get_or_apply_level_expr '[' expr ']' // x[y] + | get_or_apply_level_expr '(' (expr (',' expr)*)? ')'; // f(x, y) // Value expressions value_expr: @@ -154,3 +149,4 @@ COLON: ':'; SEMICOLON: ';'; COMMA: ','; WS: [ \t\r\n]+ -> skip; +COMMENT: '//' ~[\r\n]* -> skip; diff --git a/riscv_rt/src/lib.zig b/riscv_rt/src/lib.zig index 19d3ca3..2fecd4a 100644 --- a/riscv_rt/src/lib.zig +++ b/riscv_rt/src/lib.zig @@ -2,12 +2,17 @@ const std = @import("std"); var arena_alloc: std.heap.ArenaAllocator = undefined; var allocator: std.mem.Allocator = undefined; +var stdin: std.fs.File = undefined; +var stdout: std.fs.File = undefined; // we don't need to free the memory, so we can just use a dead large arena, and never releasing it // until the program exits :) pub fn init_allocator() void { arena_alloc = std.heap.ArenaAllocator.init(std.heap.page_allocator); allocator = arena_alloc.allocator(); + // stdin = std.io.bufferedReader(std.io.getStdIn()); + stdin = std.io.getStdIn(); + stdout = std.io.getStdOut(); } pub fn deinit_allocator() void { @@ -16,56 +21,81 @@ pub fn deinit_allocator() void { allocator = undefined; } -export fn mincaml_print_int(i: i32) void { +export fn minimbt_read_int() i32 { + var buf: [512]u8 = undefined; + if (stdin.reader().readUntilDelimiterOrEof(buf[0..], '\n') catch return std.math.minInt(i32)) |i| { + return std.fmt.parseInt(i32, i, 10) catch return std.math.minInt(i32); + } else { + return std.math.minInt(i32); + } +} + +export fn minimbt_read_char() i32 { + var buf: [1]u8 = undefined; + const sz = stdin.read(buf[0..]) catch return -1; + if (sz > 0) { + return buf[0]; + } else { + return -1; + } +} + +export fn minimbt_print_int(i: i32) void { std.debug.print("{d}", .{i}); } -export fn mincaml_print_newline() void { +export fn minimbt_print_endline() void { std.debug.print("\n", .{}); } -export fn mincaml_int_of_float(f: f64) i32 { +export fn minimbt_print_char(ch: i32) void { + const c1: u32 = @intCast(ch); + const c2: u8 = @truncate(c1); + std.debug.print("{c}", .{c2}); +} + +export fn minimbt_int_of_float(f: f64) i32 { return @intFromFloat(f); } -export fn mincaml_float_of_int(i: i32) f64 { +export fn minimbt_float_of_int(i: i32) f64 { return @floatFromInt(i); } -export fn mincaml_truncate(f: f64) i32 { +export fn minimbt_truncate(f: f64) i32 { return @intFromFloat(f); } -export fn mincaml_floor(f: f64) i32 { +export fn minimbt_floor(f: f64) i32 { return @intFromFloat(@floor(f)); } -export fn mincaml_abs_float(f: f64) f64 { +export fn minimbt_abs_float(f: f64) f64 { return @abs(f); } -export fn mincaml_sqrt(f: f64) f64 { +export fn minimbt_sqrt(f: f64) f64 { return @sqrt(f); } -export fn mincaml_sin(f: f64) f64 { +export fn minimbt_sin(f: f64) f64 { return @sin(f); } -export fn mincaml_cos(f: f64) f64 { +export fn minimbt_cos(f: f64) f64 { return @cos(f); } -export fn mincaml_atan(f: f64) f64 { +export fn minimbt_atan(f: f64) f64 { return std.math.atan(f); } -export fn mincaml_malloc(sz: usize) [*]u8 { - const payload = allocator.allocWithOptions(u8, sz, @alignOf(usize), null) catch @panic("Aalloc failed!"); +export fn minimbt_malloc(sz: u32) [*]u8 { + const payload = allocator.allocWithOptions(u8, sz, @alignOf(u32), null) catch @panic("Aalloc failed!"); return @ptrCast(payload); } -export fn mincaml_create_array(n: usize, v: i32) [*]i32 { +export fn minimbt_create_array(n: u32, v: i32) [*]i32 { const arr = allocator.alloc(i32, n) catch @panic("Alloc failed!"); for (arr) |*item| { item.* = v; @@ -73,15 +103,15 @@ export fn mincaml_create_array(n: usize, v: i32) [*]i32 { return @ptrCast(arr); } -export fn mincaml_create_ptr_array(n: usize, init: usize) [*]usize { - const arr = allocator.alloc(usize, n) catch @panic("Alloc failed!"); +export fn minimbt_create_ptr_array(n: u32, init: u32) [*]u32 { + const arr = allocator.alloc(u32, n) catch @panic("Alloc failed!"); for (arr) |*item| { item.* = init; } return @ptrCast(arr); } -export fn mincaml_create_float_array(n: usize, v: f64) [*]f64 { +export fn minimbt_create_float_array(n: u32, v: f64) [*]f64 { const arr = allocator.alloc(f64, n) catch @panic("Alloc failed!"); for (arr) |*item| { item.* = v; @@ -89,62 +119,63 @@ export fn mincaml_create_float_array(n: usize, v: f64) [*]f64 { return @ptrCast(arr); } -export fn print_int(i: i32) void { - mincaml_print_int(i); +// Compatibility functions for mincaml +export fn mincaml_print_int(i: i32) void { + minimbt_print_int(i); } -export fn print_newline() void { - mincaml_print_newline(); +export fn mincaml_print_endline() void { + minimbt_print_endline(); } -export fn int_of_float(f: f64) i32 { - return mincaml_int_of_float(f); +export fn mincaml_int_of_float(f: f64) i32 { + return minimbt_int_of_float(f); } -export fn float_of_int(i: i32) f64 { - return mincaml_float_of_int(i); +export fn mincaml_float_of_int(i: i32) f64 { + return minimbt_float_of_int(i); } -export fn truncate(f: f64) i32 { - return mincaml_truncate(f); +export fn mincaml_truncate(f: f64) i32 { + return minimbt_truncate(f); } -export fn floor(f: f64) i32 { - return mincaml_floor(f); +export fn mincaml_floor(f: f64) i32 { + return minimbt_floor(f); } -export fn abs_float(f: f64) f64 { - return mincaml_abs_float(f); +export fn mincaml_abs_float(f: f64) f64 { + return minimbt_abs_float(f); } -export fn sqrt(f: f64) f64 { - return mincaml_sqrt(f); +export fn mincaml_sqrt(f: f64) f64 { + return minimbt_sqrt(f); } -export fn sin(f: f64) f64 { - return mincaml_sin(f); +export fn mincaml_sin(f: f64) f64 { + return minimbt_sin(f); } -export fn cos(f: f64) f64 { - return mincaml_cos(f); +export fn mincaml_cos(f: f64) f64 { + return minimbt_cos(f); } -export fn atan(f: f64) f64 { - return mincaml_atan(f); +export fn mincaml_atan(f: f64) f64 { + return minimbt_atan(f); } -export fn malloc(sz: usize) [*]u8 { - return mincaml_malloc(sz); +export fn mincaml_malloc(sz: u32) [*]u8 { + return minimbt_malloc(sz); } -export fn create_array(n: usize, v: i32) [*]i32 { - return mincaml_create_array(n, v); +export fn mincaml_create_array(n: u32, v: i32) [*]i32 { + return minimbt_create_array(n, v); } -export fn create_ptr_array(n: usize, init: usize) [*]usize { - return mincaml_create_ptr_array(n, init); +export fn mincaml_create_ptr_array(n: u32, init: u32) [*]u32 { + return minimbt_create_ptr_array(n, init); } -export fn create_float_array(n: usize, v: f64) [*]f64 { - return mincaml_create_float_array(n, v); +export fn mincaml_create_float_array(n: u32, v: f64) [*]f64 { + return minimbt_create_float_array(n, v); }