aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexis Lockwood2021-06-27 20:14:25 -0400
committerAlexis Lockwood2021-06-27 20:14:25 -0400
commit5c3b9c51ffd1819a68e075bb5be78a598a31fa4c (patch)
tree579657427a233246812b0e27961c63512a70aca9
parent424e126264857e25b58cada5b6510a64336509ee (diff)
Misc changes (sorry)
-rw-r--r--Makefile9
-rw-r--r--README60
-rw-r--r--examples/fib.bas2
-rw-r--r--ls_minify.c72
-rw-r--r--ls_run.c27
-rw-r--r--src/ls.h5
-rw-r--r--src/ls_internal.c1
-rw-r--r--test/tsupport.c1
8 files changed, 112 insertions, 65 deletions
diff --git a/Makefile b/Makefile
index c4a1b27..3925440 100644
--- a/Makefile
+++ b/Makefile
@@ -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 > $@
diff --git a/README b/README
index 7752b02..d9b73d5 100644
--- a/README
+++ b/README
@@ -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;
diff --git a/ls_run.c b/ls_run.c
index 36e8696..50fbe02 100644
--- a/ls_run.c
+++ b/ls_run.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/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;
}
diff --git a/src/ls.h b/src/ls.h
index 65787e7..ea8b234 100644
--- a/src/ls.h
+++ b/src/ls.h
@@ -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;