Implement reading of code from files in the entry point

This commit is contained in:
Konstantin Nazarov 2024-08-18 20:01:40 +01:00
parent 7d88d483df
commit dbf52344ae
Signed by: knazarov
GPG key ID: 4CFE0A42FA409C22
8 changed files with 78 additions and 10 deletions

View file

@ -20,6 +20,7 @@ target_sources(vm_lib
src/utf8.cpp
src/compiler.cpp
src/opcode.cpp
src/fio.cpp
PUBLIC
FILE_SET HEADERS
@ -37,6 +38,7 @@ target_sources(vm_lib
src/utf8.hpp
src/compiler.hpp
src/opcode.hpp
src/fio.hpp
)
add_executable(vli src/vli.cpp)

View file

@ -69,7 +69,7 @@ To run:
```sh
cmake .
make
./vli
./vli example.vli
```
To run tests:

3
example.vli Normal file
View file

@ -0,0 +1,3 @@
;; Check that lambdas can be passed as arguments
((lambda (f y) (f y)) (lambda (x) (* x x)) 2)

View file

@ -459,8 +459,7 @@ class String : public Object {
return _value->data[idx];
}
Result<String> concat(const char* rhs) {
uint64_t rhs_size = strlen(rhs);
Result<String> concat(const char* rhs, uint64_t rhs_size) {
uint64_t lhs_size = size();
uint64_t res_size = lhs_size + rhs_size;
@ -473,6 +472,8 @@ class String : public Object {
return String(TRY(MkGcRoot(pod)));
}
Result<String> concat(const char* rhs) { return concat(rhs, strlen(rhs)); }
Result<String> concat(const char32_t* rhs, uint64_t rhs_size) {
uint64_t lhs_size = size();
uint64_t res_size = lhs_size + rhs_size;

View file

@ -15,6 +15,7 @@ enum class ErrorCode {
EndOfProgram,
CompilationError,
ArgumentCountMismatch,
IOError,
};
void seterr(const char* err);

39
src/fio.cpp Normal file
View file

@ -0,0 +1,39 @@
#include "fio.hpp"
#include <cstdlib>
Result<String> read_fh(FILE* file) {
size_t chunk_size = 1024;
const size_t buf_size = chunk_size;
size_t pos = 0;
char buf[chunk_size];
String res = TRY(String::create(""));
while (1) {
size_t num_bytes = fread(&buf[pos], 1, chunk_size, file);
if (ferror(stdin)) {
return ERROR(IOError);
}
res = TRY(res.concat(buf, num_bytes));
if (num_bytes < chunk_size) break;
}
return std::move(res);
}
Result<String> read_file(const char* filename) {
FILE* fh = fopen(filename, "r");
if (!fh) {
return ERROR(IOError);
}
auto res = read_fh(fh);
fclose(fh);
return res;
}
Result<String> read_stdin() { return read_fh(stdin); }

7
src/fio.hpp Normal file
View file

@ -0,0 +1,7 @@
#pragma once
#include "common.hpp"
Result<String> read_file(const char* filename);
Result<String> read_stdin();

View file

@ -1,20 +1,35 @@
#include <unistd.h>
#include <cstdio>
#include <iostream>
#include "arena.hpp"
#include "common.hpp"
#include "compiler.hpp"
#include "die.hpp"
#include "fio.hpp"
#include "reader.hpp"
#include "vm.hpp"
#include "writer.hpp"
StaticArena<64 * 1024 * 1024> arena;
Result<void> run() {
// auto code_str = TRY(String::create("(* (+ 1 2 3) (/ 4 2))"));
auto code_str =
TRY(String::create("((lambda (f y) (f y)) (lambda (x) (* x x)) 2)"));
Result<void> run(int argc, const char* argv[]) {
String src = DIEX(String::create(""));
if (argc == 1) {
if (isatty(STDIN_FILENO)) {
die("Code expected at stdin, not a tty.\n");
}
src = TRY(read_stdin());
} else {
src = TRY(read_file(argv[1]));
}
auto parsed = TRY(read_one(code_str));
// auto code_str = TRY(String::create("(* (+ 1 2 3) (/ 4 2))"));
// auto code_str =
// TRY(String::create("((lambda (f y) (f y)) (lambda (x) (* x x)) 2)"));
auto parsed = TRY(read_one(src));
auto code_str_written = TRY(write_one(parsed));
TRY(arena_gc());
@ -36,7 +51,7 @@ Result<void> run() {
return Result<void>();
}
int main() {
DIEX(run());
int main(int argc, const char* argv[]) {
DIEX(run(argc, argv));
return 0;
}