-
Notifications
You must be signed in to change notification settings - Fork 489
Add stdio.write import for writing a sequence of bytes to stdout #121
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,50 @@ | ||
open Source | ||
open Eval | ||
open Memory | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It looks like this open may be similarly unneeded. |
||
open Types | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (Sorry for nit-picking these There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have no idea. How do the rules work? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I assume it's just: if you're not using any of the things in the module, you don't need the open. I was hoping it would be just a matter of deleting the open, seeing if everything still compiles, and if so, go with it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A good rule is to limit |
||
|
||
let print vs = | ||
let print m vs = | ||
List.iter Print.print_value (List.map (fun v -> Some v) vs); | ||
None | ||
|
||
let rec stdout_write_inner at mem offset count i = | ||
let load_result = Memory.load_extend mem (Int64.add offset i) Mem8 ZX Int32Type in | ||
|
||
begin | ||
match load_result with | ||
| Values.Int32 byte -> | ||
print_char (Char.chr (Int32.to_int byte)) | ||
| _ -> | ||
ignore (Error.error at "load_extend returned wrong type") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would this be a use case where an There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Dunno. Don't know anything about |
||
end; | ||
|
||
let next = Int64.succ i in | ||
let should_iterate = (Int64.compare next count) < 0 in | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this equivalent to using plain There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When I tried |
||
|
||
if should_iterate then | ||
ignore (stdout_write_inner at mem offset count next) | ||
else | ||
(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If I understand what's going on here, the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think I was getting type errors before, but it might have been because I had a diagnostic print in there. It'll probably work if I remove the else. |
||
|
||
and stdout_write at m vs = | ||
if List.length vs != 2 then | ||
Error.error at "stdio.write expects 2 arguments (offset, count)"; | ||
|
||
let mem = Eval.memory_for_module at m in | ||
match vs with | ||
| [Values.Int32 _offset; Values.Int32 _count] -> | ||
let offset = (Int64.of_int32 _offset) in | ||
let count = (Int64.of_int32 _count) in | ||
|
||
set_binary_mode_out stdout false; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As you mentioned elsewhere, this API does the opposite of what it first looks like. Would you mind adding a comment about this? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sure |
||
ignore (stdout_write_inner at mem offset count Int64.zero); | ||
set_binary_mode_out stdout true; | ||
None | ||
|
||
| _ -> | ||
ignore (Error.error at "stdio.write expected i32 offset, i32 count"); | ||
None | ||
|
||
let match_import i = | ||
let {Ast.module_name; func_name; func_params; func_result} = i.it in | ||
if module_name <> "stdio" then | ||
|
@@ -13,6 +54,10 @@ let match_import i = | |
if func_result <> None then | ||
Error.error i.at "stdio.print has no result"; | ||
| "write" -> | ||
if func_result <> None then | ||
Error.error i.at "stdio.write has no result"; | ||
stdout_write i.at | ||
| _ -> | ||
Error.error i.at ("no stdio." ^ func_name ^ "\"") | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
(module | ||
(import $write "stdio" "write" (param i32 i32)) | ||
|
||
(memory 4096 4096 (segment 0 "\89\50\4e\47\0d\0a\1a\0a\00")) | ||
|
||
(func $write_png_header | ||
(call_import $write (i32.const 0) (i32.const 9)) | ||
) | ||
|
||
(export "write_png_header" $write_png_header) | ||
) | ||
|
||
(invoke "write_png_header") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From a readthrough, the only use of the Eval module in this file is the Eval.memory_for_module. Can this open be removed?