bugfix and added pretty printing
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Fri, 2 Jul 2021 19:29:59 +0000 (14:29 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Fri, 2 Jul 2021 19:29:59 +0000 (14:29 -0500)
bin/onyx
core/conv.onyx
core/stdio.onyx
modules/wasm_utils/parser.onyx [new file with mode: 0644]
src/onyxchecker.c

index 592017b57df7b408a5510425bbbf8403a581c85e..077a57cb477594c03c49e70e4f1cd9148fd6c960 100755 (executable)
Binary files a/bin/onyx and b/bin/onyx differ
index 842407d363fedc00f5dba7e5f8b4a7dc28aa2bf0..dd35531fe50aaa77c4976b91c6116cbc5b048075 100644 (file)
@@ -252,7 +252,10 @@ str_format_va :: (format: str, buffer: [] u8, va: [] any) -> str {
     output := Output.{ buffer.data, 0, buffer.count };
 
     Format :: struct {
+        pretty_printing      := false;
         digits_after_decimal := cast(u32) 4;
+
+        indentation := cast(u32) 0;
     }
 
     vararg_index := 0;
@@ -289,6 +292,11 @@ str_format_va :: (format: str, buffer: [] u8, va: [] any) -> str {
                         formatting.digits_after_decimal = digits;
                     }
 
+                    case #char "p" {
+                        i += 1;
+                        formatting.pretty_printing = true;
+                    }
+
                     case #default do break break;
                 }
             }
@@ -387,14 +395,31 @@ str_format_va :: (format: str, buffer: [] u8, va: [] any) -> str {
 
                     if s.name.count > 0 do output->write(s.name);
                     output->write(" { ");
-                    
-                    for ^member: s.members {
-                        if member != s.members.data do output->write(", ");
 
-                        output->write(member.name);
-                        output->write(" = ");
+                    {
+                        format := formatting;
+                        if format.pretty_printing {
+                            format.indentation += 4;
+                        }
+                        
+                        for ^member: s.members {
+                            if member != s.members.data do output->write(", ");
+
+                            if formatting.pretty_printing {
+                                output->write(#char "\n");
+                                for i: format.indentation do output->write(#char " ");
+                            }
+
+                            output->write(member.name);
+                            output->write(" = ");
 
-                        print_any(output, formatting, .{ ~~(cast(^u8) v.data + member.offset), member.type });
+                            print_any(output, format, .{ ~~(cast(^u8) v.data + member.offset), member.type });
+                        }
+                    }
+                    
+                    if formatting.pretty_printing {
+                        output->write(#char "\n");
+                        for i: formatting.indentation - 1 do output->write(#char " ");
                     }
 
                     output->write(" }");
@@ -429,13 +454,30 @@ str_format_va :: (format: str, buffer: [] u8, va: [] any) -> str {
                     data  := arr.data;
                     count := arr.count;
 
+                    format := formatting;
+                    if format.pretty_printing do format.indentation += 2;
+
                     for i: count {
                         if i != 0 do output->write(", ");
 
-                        print_any(output, formatting, .{ ~~(cast(^u8) data + get_type_info(a.of).size * i), a.of });
+                        if formatting.pretty_printing {
+                            output->write("\n");
+                            for _: format.indentation do output->write(#char " ");
+                        }
+
+                        print_any(output, format, .{ ~~(cast(^u8) data + get_type_info(a.of).size * i), a.of });
+                    }
+
+
+                    if formatting.pretty_printing {
+                        format.indentation -= 2;
+                        output->write("\n");
+                        for _: format.indentation do output->write(#char " ");
+                        output->write(#char "]");
+
+                    } else {
+                        output->write(" ]");
                     }
-                    
-                    output->write(" ]");
                 }
 
                 if info.kind == .Array {
index 51c9adea096c7512889379b031e2defe2740b7d8..a28e47354e2a923d815b585e67d9be244387a68a 100644 (file)
@@ -30,8 +30,8 @@ println :: (x: $T) {
 }
 
 printf :: (format: str, va: ..any) {
-    buffer: [2048] u8;
-    print(conv.str_format_va(format, buffer[0 .. 2048], ~~va));
+    buffer: [8196] u8;
+    print(conv.str_format_va(format, ~~buffer, ~~va));
 }
 
 // This works on both slices and arrays
diff --git a/modules/wasm_utils/parser.onyx b/modules/wasm_utils/parser.onyx
new file mode 100644 (file)
index 0000000..006b415
--- /dev/null
@@ -0,0 +1,165 @@
+//
+// Sections that still need to be parse-able
+//    - Function
+//    - Table
+//    - Memory
+//    - Global
+//    - Start
+//    - Element
+//    - Code
+//    - Data
+//    - DataCount
+
+
+package wasm_utils
+
+// The allocator to be used for all allocations in the parser. This is set when
+// calling any of the top-level parsing functions. Because this is here, it is
+// unsafe to use this library in a multi-threaded context, if Wasm ever officially
+// supports that.
+#private_file wasm_allocator : Allocator
+
+parse_type_section :: (use bin: ^WasmBinary, allocator := context.allocator) -> [] WasmFuncType {
+    if !map.has(^sections, .Type) do return .{ null, 0 };
+    wasm_allocator = allocator;
+
+    @Cleanup @WasmStream // These are going to be needed in many places
+    stream := io.string_stream_make(data);   
+    reader := io.reader_make(^stream);
+
+    io.stream_seek(^stream, map.get(^sections, .Type).offset, .Start);
+
+    return parse_vector(^reader, bin, read_func_type);
+
+    read_func_type :: (reader: ^io.Reader, binary: ^WasmBinary) -> WasmFuncType {
+        _, pos := io.stream_tell(reader.stream);
+
+        assert(io.read_byte(reader) == ~~0x60, "function type expected 0x60 as first byte");
+
+        params  := parse_vector(reader, binary, read_val_type); 
+        results := parse_vector(reader, binary, read_val_type);
+
+        _, after_pos := io.stream_tell(reader.stream);
+
+        return .{
+            params = params,
+            results = results,
+            reference = binary.data.data[pos .. ~~(after_pos - pos)],
+        };
+    }
+}
+
+parse_import_section :: (use bin: ^WasmBinary, allocator := context.allocator) -> [] WasmImport {
+    if !map.has(^sections, .Import) do return .{ null, 0 };
+
+    wasm_allocator = allocator;
+
+    @Cleanup @WasmStream // These are going to be needed in many places
+    stream := io.string_stream_make(data);   
+    reader := io.reader_make(^stream);
+
+    io.stream_seek(^stream, map.get(^sections, .Import).offset, .Start);
+
+    return parse_vector(^reader, bin, read_import);
+
+    read_import :: (reader: ^io.Reader, binary: ^WasmBinary) -> WasmImport {
+        module_name := parse_name(reader, binary);
+        import_name := parse_name(reader, binary);
+
+        kind  := io.read_byte(reader);
+        index := read_uleb128(reader);
+        
+        return .{ module_name, import_name, ~~kind, ~~index };
+    }
+}
+
+parse_export_section :: (use bin: ^WasmBinary, allocator := context.allocator) -> [] WasmExport {
+    if !map.has(^sections, .Export) do return .{ null, 0 };
+
+    wasm_allocator = allocator;
+
+    @Cleanup @WasmStream // These are going to be needed in many places
+    stream := io.string_stream_make(data);   
+    reader := io.reader_make(^stream);
+
+    io.stream_seek(^stream, map.get(^sections, .Export).offset, .Start);
+
+    return parse_vector(^reader, bin, read_export);
+
+    read_export :: (reader: ^io.Reader, binary: ^WasmBinary) -> WasmExport {
+        name := parse_name(reader, binary);
+
+        kind  := io.read_byte(reader);
+        index := read_uleb128(reader);
+        
+        return .{ name, ~~kind, ~~index };
+    }
+}
+
+parse_function_section :: (use bin: ^WasmBinary, allocator := context.allocator) -> [] WasmFunction {
+    if !map.has(^sections, .Function) do return .{ null, 0 };
+
+    wasm_allocator = allocator;
+
+    @Cleanup @WasmStream // These are going to be needed in many places
+    stream := io.string_stream_make(data);   
+    reader := io.reader_make(^stream);
+
+    io.stream_seek(^stream, map.get(^sections, .Function).offset, .Start);
+
+    return parse_vector(^reader, bin, read_function);
+
+    read_function :: (reader: ^io.Reader, binary: ^WasmBinary) -> WasmFunction {
+        return .{ ~~read_uleb128(reader) }; 
+    }
+}
+
+parse_start_section :: (use bin: ^WasmBinary, allocator := context.allocator) -> i32 {
+    if !map.has(^sections, .Start) do return -1;
+
+    @Cleanup @WasmStream // These are going to be needed in many places
+    stream := io.string_stream_make(data);   
+    reader := io.reader_make(^stream);
+
+    io.stream_seek(^stream, map.get(^sections, .Function).offset, .Start);
+
+    return ~~read_uleb128(^reader);
+}
+
+#private
+parse_vector :: (reader: ^io.Reader, bin: ^WasmBinary,
+                 read: (^io.Reader, ^WasmBinary) -> $T) -> [] T {
+    
+    n := cast(u32) read_uleb128(reader);
+    result := memory.make_slice(T, n, allocator=wasm_allocator);
+
+    for i: n {
+        result[i] = read(reader, bin);
+    }
+
+    return result;
+}
+
+#private
+parse_name :: (reader: ^io.Reader, bin: ^WasmBinary) -> [] u8 {
+    return parse_vector(reader, bin, read_byte);
+
+    read_byte :: (reader: ^io.Reader, bin: ^WasmBinary) -> u8 {
+        return io.read_byte(reader);
+    }
+}
+
+#private
+read_val_type :: (reader: ^io.Reader, binary: ^WasmBinary) -> WasmValueType {
+    byte := io.read_byte(reader);
+    switch byte {
+        case 127 do return .I32;
+        case 126 do return .I64;
+        case 125 do return .F32;
+        case 124 do return .F64;
+        case 123 do return .V128;
+        case #default do assert(false, "Bad wasm value type");
+    }
+
+    return ~~0;
+}
index b01fcbda9dae6256c042a2773a8b3b564d106c6b..d5ee283768dec572ee0277b5f78777d44d7b986a 100644 (file)
@@ -1601,6 +1601,7 @@ CheckStatus check_expression(AstTyped** pexpr) {
             //         break;
             //     }
             // }
+            if (expr->type == NULL) return Check_Yield_Macro;
 
             expr->flags |= Ast_Flag_Function_Used;
             break;