From efa6fe674f2b325138613660269de1217cc90f38 Mon Sep 17 00:00:00 2001 From: dtb Date: Fri, 9 Dec 2022 16:33:04 -0500 Subject: [PATCH 1/9] modular ops (untested) --- src/ops.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/ops.h | 4 +++ 2 files changed, 94 insertions(+) create mode 100644 src/ops.c create mode 100644 src/ops.h diff --git a/src/ops.c b/src/ops.c new file mode 100644 index 0000000..001dc3b --- /dev/null +++ b/src/ops.c @@ -0,0 +1,90 @@ +#include +#include + +#include "blang.h" + +/* no-op */ +void Ops_bang(struct State *s){ + return; +} + +void Ops_dollar(struct State *s){ + s->chart = (char *)0; +} + +void Ops_percent(struct State *s){ + *(s->chart) = s->hand; +} + +void Ops_carat(struct State *s){ + s->state = 0; +} + +void Ops_ampersand(struct State *s){ + s->hand = s->chart; +} + +void Ops_plus(struct State *s){ + ++(s->state); +} + +void Ops_dash(struct State *s){ + --(s->state); +} + +void Ops_right(struct State *s){ + putc((char)s->state, stdout); +} + +void Ops_left(struct State *s){ + s->state = getc(stdin); +} + +void Ops_semi(struct State *s){ + while( + (c = getc(stdin)) != EOF + && strchr("!\n", c) == NULL + ); +} + +void Ops_cross(struct State *s){ + char *i; + i = s->chart; + s->chart = (char *)s->hand; + s->hand = (unsigned char)i; +} + +const struct { + unsigned char name; + void (*f)(struct State *); +} *OPS[] = { + { '$', Ops_dollar }, + { '%', Ops_percent }, + { '^', Ops_caret }, + { '&', Ops_ampersand }, + { '*', Ops_splat }, + { '+', Ops_plus }, + { '-', Ops_dash }, + { '>', Ops_right }, + { '<', Ops_left }, + { 'x', Ops_cross }, + + /* no-ops */ + { '!', Ops_bang }, + { ' ', Ops_bang }, + { '\n', Ops_bang }, + { '\r', Ops_bang }, + { '\t', Ops_bang }, + { '\v', Ops_bang } +}; + +/* Slower than a switch but you don't have to update it when you add new + * ops! */ +(void(struct State *)) Ops_lookup(char op){ + size_t i; + + for(i = 0; i < (sizeof OPS)/(sizeof *OPS); ++i) + if(op == OPS[i].name) + return OPS[i].f; + return NULL; +} diff --git a/src/ops.h b/src/ops.h new file mode 100644 index 0000000..0afee19 --- /dev/null +++ b/src/ops.h @@ -0,0 +1,4 @@ +#if !defined _BLANG_OPS +# define _BLANG_OPS 1 +(void(struct State *)) Ops_lookup(char op); +#endif -- 2.30.2 From 905a0e9056e9c3d50be568f878d211e8e8b038f4 Mon Sep 17 00:00:00 2001 From: dtb Date: Fri, 9 Dec 2022 19:26:10 -0500 Subject: [PATCH 2/9] fix most compiler errors --- Makefile | 12 ++++++++++-- src/blang.c | 50 ++++++++++++++++---------------------------------- src/blang.h | 7 +++++++ src/ops.c | 18 +++++++++--------- 4 files changed, 42 insertions(+), 45 deletions(-) create mode 100644 src/blang.h diff --git a/Makefile b/Makefile index 6a59115..d86b1cf 100644 --- a/Makefile +++ b/Makefile @@ -9,8 +9,16 @@ clean: bin: mkdir -p bin +build: + mkdir -p build -bin/blang: bin src/*.c - $(CC) $(CFLAGS) -o $@ src/*.c +build/blang.o: build src/blang.c src/blang.h + $(CC) -c -o $@ src/blang.c + +build/ops.o: build src/blang.h src/ops.c src/ops.h + $(CC) -c -o $@ src/ops.c + +bin/blang: bin build/blang.o build/ops.o + $(CC) $(CFLAGS) -o $@ build/*.o .PHONY: all clean diff --git a/src/blang.c b/src/blang.c index 400bf44..db345b6 100644 --- a/src/blang.c +++ b/src/blang.c @@ -1,42 +1,24 @@ #include #include -static unsigned char get = 0; -static unsigned char _stack[4]; -static unsigned char *stack = _stack; -static unsigned char *state; +#include "blang.h" +#include "ops.h" -int main(){ +int main(int argc, char **argv){ + struct State s; int c; - while((c = getchar()) != EOF){ - if(stack == (unsigned char *)0) - return (char)state; - if(get){ - state = (char *)c; - get = 0; + void (*op)(struct State *); + + s.chart = *argv; + + while((c = getc(stdin)) != EOF){ + /* proper exit is ^* */ + if(s.chart == (char *)0) + return (int)s.hand; + if((op = Ops_lookup(c)) == NULL) continue; - } - switch(c){ - case ' ': - case '\n': - case '\r': - case '\t': - case '\v': - break; - case '!': state = stack; break; - case '$': stack = state; state = (char *)*_stack; break; - case '%': *stack = (char)state; break; - case '^': state = (char *)0; break; - case '+': ++state; break; - case '-': --state; break; - case '>': putchar((char)state); break; - case '<': get = 1; break; - case ':': - while((c = getchar()) != '\n') - if(c == EOF) - goto fin; - break; - } + else + op(&s); } -fin: return 1; + return 1; } diff --git a/src/blang.h b/src/blang.h new file mode 100644 index 0000000..6a8e94e --- /dev/null +++ b/src/blang.h @@ -0,0 +1,7 @@ +#if !defined _BLANG_H +# define _BLANG_H +struct State{ + unsigned char hand; + char *chart; +} +#endif diff --git a/src/ops.c b/src/ops.c index 001dc3b..03d3643 100644 --- a/src/ops.c +++ b/src/ops.c @@ -8,36 +8,36 @@ void Ops_bang(struct State *s){ return; } -void Ops_dollar(struct State *s){ - s->chart = (char *)0; -} - void Ops_percent(struct State *s){ *(s->chart) = s->hand; } void Ops_carat(struct State *s){ - s->state = 0; + s->hand = 0; } void Ops_ampersand(struct State *s){ s->hand = s->chart; } +void Ops_splat(struct State *s){ + s->chart = s->hand; +} + void Ops_plus(struct State *s){ - ++(s->state); + ++(s->hand); } void Ops_dash(struct State *s){ - --(s->state); + --(s->hand); } void Ops_right(struct State *s){ - putc((char)s->state, stdout); + putc((char)s->hand, stdout); } void Ops_left(struct State *s){ - s->state = getc(stdin); + s->hand = getc(stdin); } void Ops_semi(struct State *s){ -- 2.30.2 From da0ec7de0153c13400cf890aad360e64fbf3a115 Mon Sep 17 00:00:00 2001 From: dtb Date: Fri, 9 Dec 2022 19:46:32 -0500 Subject: [PATCH 3/9] change blang op meanings --- README.md | 11 +++++------ src/blang.h | 2 +- src/ops.c | 14 ++++++++------ src/ops.h | 2 +- 4 files changed, 15 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 858a041..69ffb0d 100644 --- a/README.md +++ b/README.md @@ -16,11 +16,10 @@ Public domain. 2022 DTB. ## true(1) ``` -^ ; initialize state to 0 -% ; store state (0) into *stack -; stack is destroyed, state becomes the final value of *stack -; when the stack is destroyed, the program exits with the value of state -$ +^ ; initialize hand to 0 +; set the chart pointer to 0 - this destroys the chart +; and the program exits with the value of the hand +* ``` ## Hello world: @@ -28,5 +27,5 @@ $ ; the <.> construct uses '<' to store the next value literally into state, ; does so, and uses '>' to output state literally <,>< >< ->^%$ +>^* ``` diff --git a/src/blang.h b/src/blang.h index 6a8e94e..703e07c 100644 --- a/src/blang.h +++ b/src/blang.h @@ -3,5 +3,5 @@ struct State{ unsigned char hand; char *chart; -} +}; #endif diff --git a/src/ops.c b/src/ops.c index 03d3643..510c72b 100644 --- a/src/ops.c +++ b/src/ops.c @@ -1,5 +1,6 @@ #include #include +#include #include "blang.h" @@ -17,11 +18,11 @@ void Ops_carat(struct State *s){ } void Ops_ampersand(struct State *s){ - s->hand = s->chart; + s->hand = (char)s->chart; } void Ops_splat(struct State *s){ - s->chart = s->hand; + s->chart = (char *)s->hand; } void Ops_plus(struct State *s){ @@ -41,6 +42,8 @@ void Ops_left(struct State *s){ } void Ops_semi(struct State *s){ + int c; + while( (c = getc(stdin)) != EOF && strchr("!\n", c) == NULL @@ -57,10 +60,9 @@ void Ops_cross(struct State *s){ const struct { unsigned char name; void (*f)(struct State *); -} *OPS[] = { - { '$', Ops_dollar }, +} OPS[] = { { '%', Ops_percent }, - { '^', Ops_caret }, + { '^', Ops_carat }, { '&', Ops_ampersand }, { '*', Ops_splat }, { '+', Ops_plus }, @@ -80,7 +82,7 @@ const struct { /* Slower than a switch but you don't have to update it when you add new * ops! */ -(void(struct State *)) Ops_lookup(char op){ +void (*Ops_lookup(char op))(struct State *){ size_t i; for(i = 0; i < (sizeof OPS)/(sizeof *OPS); ++i) diff --git a/src/ops.h b/src/ops.h index 0afee19..a318965 100644 --- a/src/ops.h +++ b/src/ops.h @@ -1,4 +1,4 @@ #if !defined _BLANG_OPS # define _BLANG_OPS 1 -(void(struct State *)) Ops_lookup(char op); +void (*Ops_lookup(char op))(struct State *); #endif -- 2.30.2 From add3346ce9ee7c958bb47adfa91f78d03f1da899 Mon Sep 17 00:00:00 2001 From: dtb Date: Fri, 9 Dec 2022 21:03:06 -0500 Subject: [PATCH 4/9] get hello world working again, fix type issues --- src/blang.c | 12 ++++++------ src/blang.h | 16 ++++++++++++++-- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/blang.c b/src/blang.c index db345b6..1edfbed 100644 --- a/src/blang.c +++ b/src/blang.c @@ -1,3 +1,4 @@ +#include #include #include @@ -9,16 +10,15 @@ int main(int argc, char **argv){ int c; void (*op)(struct State *); - s.chart = *argv; + s.chart = *(argv+1); + s.counter = 0; - while((c = getc(stdin)) != EOF){ - /* proper exit is ^* */ + for(s.counter = 0; ; ++s.counter){ if(s.chart == (char *)0) return (int)s.hand; - if((op = Ops_lookup(c)) == NULL) - continue; + if((op = Ops_lookup(s.chart[s.counter])) == NULL) + return 127; else op(&s); } - return 1; } diff --git a/src/blang.h b/src/blang.h index 703e07c..3aba3bb 100644 --- a/src/blang.h +++ b/src/blang.h @@ -1,7 +1,19 @@ #if !defined _BLANG_H # define _BLANG_H +# include +/* This has to be big enough to hold a char * without degradation. + * Adjust to architecture/system/environment/etc. */ +typedef uint64_t hand_t; + +/* Just has to be fairly big. (TODO specify) */ +typedef uint64_t counter_t; + +/* Holds *argv; will not change between environments. */ +typedef char * chart_t; + struct State{ - unsigned char hand; - char *chart; + chart_t chart; + counter_t counter; + hand_t hand; }; #endif -- 2.30.2 From 35a3fb0d621f947de07ef4d5bdf0ac7ce41c5350 Mon Sep 17 00:00:00 2001 From: dtb Date: Fri, 9 Dec 2022 21:03:23 -0500 Subject: [PATCH 5/9] build, build/* --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index a13e547..23ce63b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ bin bin/* +build +build/* -- 2.30.2 From 6c659ee621765602de260b478b109155ca22f876 Mon Sep 17 00:00:00 2001 From: dtb Date: Fri, 9 Dec 2022 21:05:38 -0500 Subject: [PATCH 6/9] add more readme stuff --- README.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 69ffb0d..01fd0be 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,9 @@ Public domain. 2022 DTB. ## true(1) ``` -^ ; initialize hand to 0 +; initialize hand to 0 +^ + ; set the chart pointer to 0 - this destroys the chart ; and the program exits with the value of the hand * @@ -24,8 +26,8 @@ Public domain. 2022 DTB. ## Hello world: ``` -; the <.> construct uses '<' to store the next value literally into state, -; does so, and uses '>' to output state literally +; the <.> construct uses '<' to literally 'palm' the next value +; (store into hand), does so, and uses '>' to 'toss' (output hand's value) <,>< >< >^* ``` -- 2.30.2 From 6a90901f81c3a18c22a23b8bceb95b3dcfd88588 Mon Sep 17 00:00:00 2001 From: dtb Date: Fri, 9 Dec 2022 21:34:03 -0500 Subject: [PATCH 7/9] blangfile(1) --- Makefile | 4 +--- bin/blangfile | 3 +++ example/hello_world.blang | 2 ++ 3 files changed, 6 insertions(+), 3 deletions(-) create mode 100755 bin/blangfile create mode 100644 example/hello_world.blang diff --git a/Makefile b/Makefile index d86b1cf..3b07632 100644 --- a/Makefile +++ b/Makefile @@ -7,8 +7,6 @@ all: $(TARGETS) clean: $(RM) $(TARGETS) -bin: - mkdir -p bin build: mkdir -p build @@ -18,7 +16,7 @@ build/blang.o: build src/blang.c src/blang.h build/ops.o: build src/blang.h src/ops.c src/ops.h $(CC) -c -o $@ src/ops.c -bin/blang: bin build/blang.o build/ops.o +bin/blang: build/blang.o build/ops.o $(CC) $(CFLAGS) -o $@ build/*.o .PHONY: all clean diff --git a/bin/blangfile b/bin/blangfile new file mode 100755 index 0000000..329e92f --- /dev/null +++ b/bin/blangfile @@ -0,0 +1,3 @@ +#!/bin/sh + +blang "$(cat "$@")" diff --git a/example/hello_world.blang b/example/hello_world.blang new file mode 100644 index 0000000..0c7b749 --- /dev/null +++ b/example/hello_world.blang @@ -0,0 +1,2 @@ +<,>< >< +>^* -- 2.30.2 From 193254fb1f0c60419607db5331ed39be73df7631 Mon Sep 17 00:00:00 2001 From: dtb Date: Fri, 9 Dec 2022 21:59:24 -0500 Subject: [PATCH 8/9] more doc --- .gitignore | 3 +-- README.md | 6 +++--- example/true.blang | 2 ++ 3 files changed, 6 insertions(+), 5 deletions(-) create mode 100644 example/true.blang diff --git a/.gitignore b/.gitignore index 23ce63b..8e5688b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ -bin -bin/* +bin/blang build build/* diff --git a/README.md b/README.md index 01fd0be..dd624ba 100644 --- a/README.md +++ b/README.md @@ -12,9 +12,9 @@ the bang language Public domain. 2022 DTB. -# Examples +## Examples -## true(1) +### true(1) ``` ; initialize hand to 0 ^ @@ -24,7 +24,7 @@ Public domain. 2022 DTB. * ``` -## Hello world: +### Hello world: ``` ; the <.> construct uses '<' to literally 'palm' the next value ; (store into hand), does so, and uses '>' to 'toss' (output hand's value) diff --git a/example/true.blang b/example/true.blang new file mode 100644 index 0000000..c01d48b --- /dev/null +++ b/example/true.blang @@ -0,0 +1,2 @@ +#!/usr/bin/env blangfile +^* -- 2.30.2 From 2e9cd207614e40f94539d503d7334f13aa8ba4f5 Mon Sep 17 00:00:00 2001 From: dtb Date: Fri, 9 Dec 2022 21:59:48 -0500 Subject: [PATCH 9/9] mirror and brackets --- src/blang.c | 6 +++--- src/blang.h | 6 ++---- src/ops.c | 36 ++++++++++++++++++++++++++++-------- 3 files changed, 33 insertions(+), 15 deletions(-) diff --git a/src/blang.c b/src/blang.c index 1edfbed..88a48ef 100644 --- a/src/blang.c +++ b/src/blang.c @@ -11,12 +11,12 @@ int main(int argc, char **argv){ void (*op)(struct State *); s.chart = *(argv+1); - s.counter = 0; + s.counter = s.chart; - for(s.counter = 0; ; ++s.counter){ + for(s.counter = s.chart; ; ++s.counter){ if(s.chart == (char *)0) return (int)s.hand; - if((op = Ops_lookup(s.chart[s.counter])) == NULL) + if((op = Ops_lookup(*s.counter)) == NULL) return 127; else op(&s); diff --git a/src/blang.h b/src/blang.h index 3aba3bb..1179111 100644 --- a/src/blang.h +++ b/src/blang.h @@ -5,15 +5,13 @@ * Adjust to architecture/system/environment/etc. */ typedef uint64_t hand_t; -/* Just has to be fairly big. (TODO specify) */ -typedef uint64_t counter_t; - /* Holds *argv; will not change between environments. */ typedef char * chart_t; struct State{ chart_t chart; - counter_t counter; + chart_t point; + chart_t counter; hand_t hand; }; #endif diff --git a/src/ops.c b/src/ops.c index 510c72b..998edc1 100644 --- a/src/ops.c +++ b/src/ops.c @@ -18,7 +18,7 @@ void Ops_carat(struct State *s){ } void Ops_ampersand(struct State *s){ - s->hand = (char)s->chart; + s->hand = (uint64_t)s->chart; } void Ops_splat(struct State *s){ @@ -33,42 +33,62 @@ void Ops_dash(struct State *s){ --(s->hand); } +void Ops_lbrack(struct State *s){ + s->point = s->counter; +} + +void Ops_rbrack(struct State *s){ + s->counter = s->point; +} + +void Ops_left(struct State *s){ + s->hand = *++s->counter; +} + void Ops_right(struct State *s){ putc((char)s->hand, stdout); } -void Ops_left(struct State *s){ - s->hand = getc(stdin); +void Ops_what(struct State *s){ + if(!s->hand) + ++(s->counter); } void Ops_semi(struct State *s){ int c; - while( - (c = getc(stdin)) != EOF - && strchr("!\n", c) == NULL - ); + while(strchr("!\n", *++s->counter) == NULL); +} + +void Ops_mirror(struct State *s){ + s->hand = !s->hand; } void Ops_cross(struct State *s){ char *i; i = s->chart; s->chart = (char *)s->hand; - s->hand = (unsigned char)i; + s->hand = (uint64_t)i; } const struct { unsigned char name; void (*f)(struct State *); } OPS[] = { + { '#', Ops_semi }, { '%', Ops_percent }, { '^', Ops_carat }, { '&', Ops_ampersand }, { '*', Ops_splat }, { '+', Ops_plus }, { '-', Ops_dash }, + { '{', Ops_lbrack }, + { '}', Ops_rbrack }, + { ';', Ops_semi }, { '>', Ops_right }, { '<', Ops_left }, + { '?', Ops_what }, + { 'v', Ops_mirror }, { 'x', Ops_cross }, /* no-ops */ -- 2.30.2