diff options
author | Alexis Lockwood | 2021-06-27 20:14:25 -0400 |
---|---|---|
committer | Alexis Lockwood | 2021-06-27 20:14:25 -0400 |
commit | 5c3b9c51ffd1819a68e075bb5be78a598a31fa4c (patch) | |
tree | 579657427a233246812b0e27961c63512a70aca9 | |
parent | 424e126264857e25b58cada5b6510a64336509ee (diff) |
Misc changes (sorry)
-rw-r--r-- | Makefile | 9 | ||||
-rw-r--r-- | README | 60 | ||||
-rw-r--r-- | examples/fib.bas | 2 | ||||
-rw-r--r-- | ls_minify.c | 72 | ||||
-rw-r--r-- | ls_run.c | 27 | ||||
-rw-r--r-- | src/ls.h | 5 | ||||
-rw-r--r-- | src/ls_internal.c | 1 | ||||
-rw-r--r-- | test/tsupport.c | 1 |
8 files changed, 112 insertions, 65 deletions
@@ -13,10 +13,11 @@ TEST_ARGS := -Imunit -Lmunit -lmunit test/tsupport.c TESTS := test/test_internal.test -CFLAGS += \ +CFLAGS := \ -O0 -ggdb \ -std=c99 -D_DEFAULT_SOURCE \ - -Wall -Wextra -Wpedantic -Wshadow -Wconversion -pedantic + -Wall -Wextra -Wpedantic -Wshadow -Wconversion -pedantic \ + ${EXTRA_FLAGS} .PHONY: all clean @@ -34,10 +35,10 @@ include ${LS_SOURCES:.c=.d} munit/munit.o: CFLAGS := $(filter-out -Wconversion -Wshadow, ${CFLAGS}) ls_run: ls_run.c src/libls.a - ${CC} $< ${LS_ARGS} -o $@ ${CFLAGS} + ${CC} $< ${LS_ARGS} -lexplain -o $@ ${CFLAGS} ls_minify: ls_minify.c src/libls.a - ${CC} $< ${LS_ARGS} -o $@ ${CFLAGS} + ${CC} $< ${LS_ARGS} -lexplain -o $@ ${CFLAGS} src/ls_kws.c: gen_kws.py $(PYTHON) gen_kws.py source > $@ @@ -21,6 +21,66 @@ embedded-friendly: This software disclaims copyright. Do what you want with it. Be gay, do crime. Originally written by Alexis Lockwood in 2021. Ⓐ +┌──────────┐ +│ Building │ +└──────────┘ + +Dependencies (for all builds): + + Python 3 + +Dependencies (command-line tools only): + + libexplain (apt install libexplain-dev) + +Building locally, running tests, and cleaning: + + make + make check + make clean + +Cross-compiling only the library: + + make CC=avr-gcc EXTRA_FLAGS=-fshort-enums + +┌──────────────────────┐ +│ So, how small is it? │ +└──────────────────────┘ + +The short answer: about 15 kB of flash and a bit over 1 kB of RAM. + +*That's not so small!* + +Well, it's Littlescript, not Microscript. Not so small that it's impractical to +use. My target platforms are RAM-limited but have plenty of flash (e.g. larger +8-bit microcontrollers like AVR-Dx and ATxmega). The flash usage is pretty +high, around 15 kB (TODO update this when closer to a release). The RAM usage, +however, is much smaller than a typical BASIC. For example, here is an +estimation of RAM usage on an 8-bit platform with 16-bit addressing like AVR: + + 64x 15B pool entries 960 + Main ls_t object 57 + 2x 64 byte buffers 128 + --------------------------- + Total usage 1145 + +All data is allocated from the pool, which can be arbitrarily sized (up to +64k entries). The 64-byte buffers listed are for storing source code, and are +not needed if the entire source is already in RAM or ROM. + +The following things use pool entries: + +- The global scope (1) +- Named labels, which are stored as they are found (1 each) +- Variables (1 each for integers, 2 each for other types, plus as many as + required for the data inside containers: each holds one list element or + 8 string characters) +- Expression evaluation (number determined by the expression complexity, + typically 2-4, these are freed when the expression is finished being + evaluated) +- GOSUB calls, to save the execution context (1, plus 1 per argument for the + new scope) + ┌───────────────────────────┐ │ What's implemented so far │ └───────────────────────────┘ diff --git a/examples/fib.bas b/examples/fib.bas index 00f468b..15e92f0 100644 --- a/examples/fib.bas +++ b/examples/fib.bas @@ -3,7 +3,7 @@ print 1, " ", n2 = 0 n1 = 1 -cnt = 4 +cnt = 10 1: n = n2 + n1 n2 = n1 diff --git a/ls_minify.c b/ls_minify.c index 4cb03ce..42a1766 100644 --- a/ls_minify.c +++ b/ls_minify.c @@ -8,6 +8,12 @@ #include "ls_internal.h" #include "ls_lex.h" +// External dependencies +#include <libexplain/ferror.h> +#include <libexplain/fopen.h> +#include <libexplain/malloc.h> +#include <libexplain/realloc.h> + // Standard headers #include <stdbool.h> #include <stddef.h> @@ -84,60 +90,46 @@ int main(int argc, char ** argv) } } + FILE * f = NULL; + if (optind >= argc) - { - _usage(argv[0], true); - exit(EXIT_FAILURE); - } + f = stdin; + else if (!strcmp(argv[optind], "-")) + f = stdin; + else + f = explain_fopen_or_die(argv[optind], "r"); - FILE * f; + size_t sz = 512, i = 0; + char * s = explain_malloc_or_die(sz); - // TODO: allow this to be - or /dev/stdin. This will require dropping - // the fstat and just growing the array as we read. Can't be arsed. - f = fopen(argv[optind], "r"); - if (!f) + while (!feof(f)) { - perror("fopen"); - exit(EXIT_FAILURE); - } + explain_ferror_or_die(f); - struct stat statbuf; - if (fstat(fileno(f), &statbuf) == -1) - { - perror("fstat"); - exit(EXIT_FAILURE); + size_t read_sz = sz - i; + size_t n = fread(&s[i], 1, sz - i, f); + i += n; + + if (read_sz == n) + { + sz *= 2; + s = explain_realloc_or_die(s, sz); + } } + if (f != stdin) + fclose(f); + file_fetcher_t fet; - assert(statbuf.st_size >= 0); - fet.len = (size_t) statbuf.st_size; - char * s = malloc(fet.len); - size_t n = fread(s, 1, fet.len, f); + fet.len = i; fet.s = s; - if (n != fet.len) - { - if (ferror(f)) - perror("fread"); - else - fprintf(stderr, - "huh? input file changed while reading\n"); - exit(EXIT_FAILURE); - } - - fclose(f); - if (optind + 1 < argc) { if (!strcmp(argv[optind + 1], "-")) f = stdout; else - f = fopen(argv[optind + 1], "w"); - if (!f) - { - perror("fopen"); - exit(EXIT_FAILURE); - } + f = explain_fopen_or_die(argv[optind + 1], "w"); } else f = stdout; @@ -165,7 +157,7 @@ static int _fetcher(void * arg, uint16_t loc) static void _usage(char const * argv0, bool short_text) { - fprintf(stderr, "usage: %s [OPTION...] SCRIPT [OUTPUT]\n", argv0); + fprintf(stderr, "usage: %s [OPTION...] [INPUT [OUTPUT]]\n", argv0); if (short_text) return; @@ -8,6 +8,12 @@ #include "ls_internal.h" #include "ls_lex.h" +// External dependencies +#include <libexplain/ferror.h> +#include <libexplain/fopen.h> +#include <libexplain/fstat.h> +#include <libexplain/calloc.h> + // Standard headers #include <stdbool.h> #include <stddef.h> @@ -88,19 +94,10 @@ int main(int argc, char ** argv) exit(EXIT_FAILURE); } - FILE * f = fopen(argv[optind], "r"); - if (!f) - { - perror("fopen"); - exit(EXIT_FAILURE); - } + FILE * f = explain_fopen_or_die(argv[optind], "r"); struct stat statbuf; - if (fstat(fileno(f), &statbuf) == -1) - { - perror("fstat"); - exit(EXIT_FAILURE); - } + explain_fstat_or_die(fileno(f), &statbuf); size_t const n_cache_pages = 3; size_t const cache_page_size = 8; // This should be bigger lol @@ -112,11 +109,13 @@ int main(int argc, char ** argv) fet.n_page = (size_t) -1; assert(statbuf.st_size >= 0); fet.total_size = (size_t) statbuf.st_size; - fet.cache = calloc(n_cache_pages, sizeof(*fet.cache)); - fet.cache_offsets = calloc(n_cache_pages, sizeof(*fet.cache_offsets)); + fet.cache = explain_calloc_or_die(n_cache_pages, sizeof(*fet.cache)); + fet.cache_offsets = explain_calloc_or_die(n_cache_pages, + sizeof(*fet.cache_offsets)); for (size_t i = 0; i < n_cache_pages; i++) { - fet.cache[i] = calloc(cache_page_size, sizeof(char)); + fet.cache[i] = explain_calloc_or_die(cache_page_size, + sizeof(char)); fet.cache_offsets[i] = (size_t) -1; } @@ -63,10 +63,7 @@ typedef struct ls_s { /// Execution stack. ls_value_t * _callstack; - /// User functions defined by DEF FN. - ls_value_t * _funcs; - - /// Named labels + /// Named labels and user functions (including DEF FN) ls_value_t * _labels; /// Data pool. All runtime values are allocated from here. diff --git a/src/ls_internal.c b/src/ls_internal.c index 3fc956e..89cc4be 100644 --- a/src/ls_internal.c +++ b/src/ls_internal.c @@ -69,7 +69,6 @@ void ls_init(ls_t * self, ls_value_t * pool, size_t szpool) }; } - self->_funcs = NULL; self->_labels = NULL; self->_pc = 0; self->stop = false; diff --git a/test/tsupport.c b/test/tsupport.c index 03a9bbe..d20b85e 100644 --- a/test/tsupport.c +++ b/test/tsupport.c @@ -33,7 +33,6 @@ void ls_test_setup(ls_t * ls, char const * text) { _setup_pool(_pool, LS_TEST_NPOOL); ls->_callstack = NULL; - ls->_funcs = NULL; ls->_pool = _pool; ls->_pc = 0; ls->_label_cache_i = 0; |