Skip to content

Commit f263fba

Browse files
File system and file operations.
1 parent 852e6a0 commit f263fba

File tree

4 files changed

+167
-22
lines changed

4 files changed

+167
-22
lines changed

compiler/compilation.go

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -318,13 +318,14 @@ func BeforeCompilation(writer *OutputWriter) {
318318
tempMaxPC := 1
319319
var pendingLabels []string
320320

321+
memSize := int32(writer.Options.Memory)
321322
sectionPointers := map[string]int32{
322323
".rodata": 1024,
323-
".data": 1024 * 1024, // 1MB
324-
".sdata": 2 * 1024 * 1024, // 2MB
325-
".bss": 3 * 1024 * 1024, // 3MB
326-
".sbss": 4 * 1024 * 1024, // 4MB
327-
".text": 5 * 1024 * 1024, // 5MB
324+
".data": memSize / 8,
325+
".sdata": 2 * memSize / 8,
326+
".bss": 3 * memSize / 8,
327+
".sbss": 4 * memSize / 8,
328+
".text": 5 * memSize / 8,
328329
}
329330
currentSection := ".text"
330331

@@ -419,11 +420,11 @@ func BeforeCompilation(writer *OutputWriter) {
419420

420421
sectionPointers = map[string]int32{
421422
".rodata": 1024,
422-
".data": 1024 * 1024,
423-
".sdata": 2 * 1024 * 1024,
424-
".bss": 3 * 1024 * 1024,
425-
".sbss": 4 * 1024 * 1024,
426-
".text": 5 * 1024 * 1024,
423+
".data": memSize / 8,
424+
".sdata": 2 * memSize / 8,
425+
".bss": 3 * memSize / 8,
426+
".sbss": 4 * memSize / 8,
427+
".text": 5 * memSize / 8,
427428
}
428429
currentSection = ".text"
429430
writer.MemoryDevelopmentPointer = sectionPointers[currentSection]
@@ -468,8 +469,8 @@ func BeforeCompilation(writer *OutputWriter) {
468469

469470
/* finish loading directives */
470471
WriteIndentedString(writer, "PC = %d\n", FindLabelAddress(writer, writer.Options.MainSymbol))
471-
WriteIndentedString(writer, "r3 = %d -- start at the center after static data\n", 8 * 1024 * 1024)
472-
WriteIndentedString(writer, "if r3 >= buffer.len(memory) then error(\"Not enough memory\") end\n")
472+
WriteIndentedString(writer, "r3 = buffer.len(memory) - 1024 -- start at the end of memory minus some padding\n")
473+
WriteIndentedString(writer, "if r3 <= 0 then error(\"Not enough memory\") end\n")
473474
writer.Depth--
474475
WriteIndentedString(writer, "end\n")
475476

@@ -511,6 +512,7 @@ func AfterCompilation(writer *OutputWriter) []byte {
511512
init = init,
512513
memory = memory,
513514
functions = functions,
515+
files = files,
514516
util = {
515517
get_args = get_args,
516518
push_args = push_args,

compiler/templates/boilerplate.luau

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ local mallocDepth: number = 0
1818
local stdout_cache: string = ""
1919
local errno: number = 0
2020
local fflags: number = 0 -- floating-point exception flags (NV,DZ,OF,UF,NX)
21+
local files: {[string]: buffer} = {}
22+
local open_files: {[number]: {buffer: buffer, pos: number, name: string}} = {}
23+
local next_fd: number = 1
2124

2225
-- Utility
2326
--- Base (can be found in generated code)
@@ -31,7 +34,7 @@ function reset_registers(): ()
3134
r17,r18,r19,r20,r21,r22,r23,r24,r25,r26,r27,r28,r29,r30,r31,r32 = 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
3235
r33,r34,r35,r36,r37,r38,r39,r40,r41,r42,r43,r44,r45,r46,r47,r48 = 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
3336
r49,r50,r51,r52,r53,r54,r55,r56,r57,r58,r59,r60,r61,r62,r63,r64 = 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
34-
r3 = mem -- x2/sp starts at top of stack
37+
r3 = mem - 1024 -- x2/sp starts at top of stack minus padding
3538
fflags = 0
3639
end
3740

compiler/templates/stdio.luau

Lines changed: 148 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,30 +32,170 @@ end
3232

3333
functions["fopen"] = function()
3434
local path_ptr, mode_ptr = get_args()
35-
-- local path = read_string(path_ptr)
35+
local path = read_string(path_ptr)
3636
-- local mode = read_string(mode_ptr)
37-
-- Just return 0 (NULL) for all file open requests for now
38-
push_args(0)
37+
38+
local file_buffer = files[path]
39+
if not file_buffer then
40+
push_args(0) -- Return NULL if file not found
41+
return
42+
end
43+
44+
local fd = next_fd
45+
next_fd += 1
46+
open_files[fd] = {
47+
buffer = file_buffer,
48+
pos = 0,
49+
name = path
50+
}
51+
push_args(fd)
3952
end
4053

4154
functions["fclose"] = function()
42-
push_args(0)
55+
local stream = get_args()
56+
if open_files[stream] then
57+
open_files[stream] = nil
58+
push_args(0)
59+
else
60+
push_args(-1) -- EOF/Error
61+
end
4362
end
4463

4564
functions["fread"] = function()
46-
push_args(0)
65+
local ptr, size, nmemb, stream = get_args()
66+
local handle = open_files[stream]
67+
if not handle or size == 0 or nmemb == 0 then
68+
push_args(0)
69+
return
70+
end
71+
72+
local total_bytes = size * nmemb
73+
local available = buffer.len(handle.buffer) - handle.pos
74+
local to_read = math.min(total_bytes, available)
75+
76+
if to_read > 0 then
77+
buffer.copy(memory, ptr, handle.buffer, handle.pos, to_read)
78+
handle.pos += to_read
79+
end
80+
81+
push_args(math.floor(to_read / size))
4782
end
4883

4984
functions["fseek"] = function()
50-
push_args(-1)
85+
local stream, offset, whence = get_args()
86+
local handle = open_files[stream]
87+
if not handle then
88+
push_args(-1)
89+
return
90+
end
91+
92+
local new_pos = handle.pos
93+
if whence == 0 then -- SEEK_SET
94+
new_pos = offset
95+
elseif whence == 1 then -- SEEK_CUR
96+
new_pos = handle.pos + offset
97+
elseif whence == 2 then -- SEEK_END
98+
new_pos = buffer.len(handle.buffer) + offset
99+
end
100+
101+
if new_pos < 0 then
102+
push_args(-1)
103+
return
104+
end
105+
106+
handle.pos = new_pos
107+
push_args(0)
51108
end
52109

53110
functions["ftell"] = function()
54-
push_args(-1)
111+
local stream = get_args()
112+
local handle = open_files[stream]
113+
if not handle then
114+
push_args(-1)
115+
return
116+
end
117+
push_args(handle.pos)
55118
end
56119

57120
functions["feof"] = function()
58-
push_args(1)
121+
local stream = get_args()
122+
local handle = open_files[stream]
123+
if not handle then
124+
push_args(1)
125+
return
126+
end
127+
push_args(handle.pos >= buffer.len(handle.buffer) and 1 or 0)
128+
end
129+
130+
functions["fgetc"] = function()
131+
local stream = get_args()
132+
local handle = open_files[stream]
133+
if not handle or handle.pos >= buffer.len(handle.buffer) then
134+
push_args(-1) -- EOF
135+
return
136+
end
137+
local c = buffer.readu8(handle.buffer, handle.pos)
138+
handle.pos += 1
139+
push_args(c)
140+
end
141+
142+
functions["fgets"] = function()
143+
local s_ptr, size, stream = get_args()
144+
local handle = open_files[stream]
145+
if not handle or size <= 0 or handle.pos >= buffer.len(handle.buffer) then
146+
push_args(0) -- NULL
147+
return
148+
end
149+
150+
local count = 0
151+
while count < size - 1 and handle.pos < buffer.len(handle.buffer) do
152+
local c = buffer.readu8(handle.buffer, handle.pos)
153+
buffer.writeu8(memory, s_ptr + count, c)
154+
handle.pos += 1
155+
count += 1
156+
if c == 10 then -- \n
157+
break
158+
end
159+
end
160+
buffer.writeu8(memory, s_ptr + count, 0)
161+
push_args(s_ptr)
162+
end
163+
164+
functions["fputc"] = function()
165+
local c, stream = get_args()
166+
local handle = open_files[stream]
167+
if not handle then
168+
push_args(-1)
169+
return
170+
end
171+
-- If we exceed buffer, we can't write more for now as buffers are fixed size
172+
if handle.pos < buffer.len(handle.buffer) then
173+
buffer.writeu8(handle.buffer, handle.pos, c)
174+
handle.pos += 1
175+
push_args(c)
176+
else
177+
push_args(-1)
178+
end
179+
end
180+
181+
functions["fwrite"] = function()
182+
local ptr, size, nmemb, stream = get_args()
183+
local handle = open_files[stream]
184+
if not handle or size == 0 or nmemb == 0 then
185+
push_args(0)
186+
return
187+
end
188+
189+
local total_bytes = size * nmemb
190+
local available = buffer.len(handle.buffer) - handle.pos
191+
local to_write = math.min(total_bytes, available)
192+
193+
if to_write > 0 then
194+
buffer.copy(handle.buffer, handle.pos, memory, ptr, to_write)
195+
handle.pos += to_write
196+
end
197+
198+
push_args(math.floor(to_write / size))
59199
end
60200

61201
functions["printf"] = function()

compiler/utils.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ func wrapU32Expr(w *OutputWriter, expr string) string {
132132
}
133133
func CompileRegister(w *OutputWriter, argument Argument) string {
134134
/* does it work as a integer (its a plain) */
135-
_, err := strconv.Atoi(argument.Source)
135+
_, err := strconv.ParseInt(argument.Source, 0, 64)
136136
if err == nil {
137137
return argument.Source
138138
}

0 commit comments

Comments
 (0)