Files
comb/eval_code_blocks.odin
2025-12-18 11:37:25 -05:00

93 lines
2.2 KiB
Odin

#+feature dynamic-literals
package comb
import os "core:os/os2"
import "core:strings"
import tt "core:testing"
LangInfo :: struct {
command: []string,
file_extension: string,
}
lang_info_map := map[string]LangInfo {
"python" = {command = {"python3", "-c"}, file_extension = ".py"},
"javascript" = {command = {"node", "-e"}, file_extension = ".js"},
"bash" = {command = {"bash", "-c"}, file_extension = ".sh"},
}
EvalError :: union #shared_nil {
enum {
None = 0,
Unknown_Language,
},
os.Error
}
eval_code_block :: proc(
cb: Code_Block,
allocator := context.allocator,
temp_allocator := context.temp_allocator,
) -> (
stdout: string,
stderr: string,
err: EvalError,
) {
info, ok := lang_info_map[cb.language]
if !ok {
err = .Unknown_Language
return
}
command := make([dynamic]string, allocator = temp_allocator)
reserve(&command, len(info.command) + 1)
for c in info.command {
append(&command, c)
}
append(&command, cb.text)
env, _ := os.environ(temp_allocator)
process_desc := os.Process_Desc {
command = command[:],
env = env,
}
state, byte_stdout, byte_stderr, os_err := os.process_exec(process_desc, allocator)
if os_err != nil {
delete(byte_stdout)
delete(byte_stderr)
err = os_err
return
}
stdout = string(byte_stdout)
stderr = string(byte_stderr)
return
}
@(test)
can_eval_code_blocks_python :: proc(t: ^tt.T) {
cb := Code_Block{
language="python",
text="print('hello world')"
}
defer free_all(context.temp_allocator)
stdout, stderr := eval_code_block(cb) or_else tt.fail_now(t, "should be able to execute code block")
defer delete(stdout)
defer delete(stderr)
tt.expect_value(t, strings.trim_space(stdout), "hello world")
tt.expect_value(t, strings.trim_space(stderr), "")
}
@(test)
can_eval_code_blocks_javascript :: proc(t: ^tt.T) {
cb := Code_Block{
language="javascript",
text="console.log('hello world')"
}
defer free_all(context.temp_allocator)
stdout, stderr := eval_code_block(cb) or_else tt.fail_now(t, "should be able to execute code block")
defer delete(stdout)
defer delete(stderr)
tt.expect_value(t, strings.trim_space(stdout), "hello world")
tt.expect_value(t, strings.trim_space(stderr), "")
}