Merge remote-tracking branch 'upstream/main' into d6/subprocess-feb2024
This commit is contained in:
commit
b9e953a490
|
@ -0,0 +1,79 @@
|
|||
( test file )
|
||||
|
||||
|0100 @program
|
||||
|
||||
#01 ?{ ( skip ) #ffff }
|
||||
!{ ( skip ) #ffff }
|
||||
{ ( skip ) #ffff } POP2r
|
||||
|
||||
( nested lambda )
|
||||
{ { "hello 0a $1 } STH2r !print-str } STH2r JSR2
|
||||
|
||||
( function application )
|
||||
{ 01 02 03 04 05 } STH2r { LIT "0 ADD #18 DEO #0a18 DEO JMP2r } STH2r foreach
|
||||
|
||||
( get lambda length )
|
||||
{ "Dindeldums $1 } STH2r get-lambda-length <print-dec> #0a18 DEO
|
||||
|
||||
( allocated string )
|
||||
;hello-word print-str
|
||||
|
||||
#800f DEO
|
||||
|
||||
BRK
|
||||
|
||||
(
|
||||
@| test label inheritance )
|
||||
|
||||
@Object &x $1 &y $1
|
||||
|
||||
&get-x ( -- x )
|
||||
,&x LDR
|
||||
JMP2r
|
||||
|
||||
@Object/get-y ( -- y )
|
||||
,&y LDR
|
||||
JMP2r
|
||||
|
||||
@Object/get-both ( -- x y )
|
||||
/get-x /get-y
|
||||
JMP2r
|
||||
|
||||
( raw lambda length )
|
||||
_{ 01 02 03 }
|
||||
|
||||
@get-lambda-length ( lambda* -- length* )
|
||||
#0002 SUB2 LDA2
|
||||
JMP2r
|
||||
|
||||
@print-str ( str* -- )
|
||||
&while ( -- )
|
||||
( send ) LDAk #18 DEO
|
||||
( loop ) INC2 LDAk ?&while
|
||||
POP2
|
||||
|
||||
JMP2r
|
||||
|
||||
@foreach ( arr* fn* -- )
|
||||
STH2
|
||||
DUP2
|
||||
DUP2 #0002 SUB2 LDA2 ADD2
|
||||
SWP2
|
||||
&l
|
||||
LDAk STH2kr JSR2
|
||||
INC2 NEQ2k ?&l
|
||||
POP2 POP2 POP2r
|
||||
JMP2r
|
||||
|
||||
@<print-dec> ( short* -- )
|
||||
#2710 [ LIT2r 00fb ]
|
||||
&w ( -- )
|
||||
DIV2k #000a DIV2k MUL2 SUB2 SWPr EQUk OVR STHkr EQU AND ?&>skip
|
||||
DUP [ LIT "0 ] ADD #19 DEO
|
||||
INCr &>skip
|
||||
POP2 #000a DIV2 SWPr INCr STHkr ?&w
|
||||
POP2r POP2 POP2 JMP2r
|
||||
|
||||
$20 @label2
|
||||
|
||||
@hello-word "Hello 20 "World! 0a $1
|
14
makefile
14
makefile
|
@ -5,28 +5,26 @@ EMU_src=${CLI_src} src/devices/screen.c src/devices/controller.c src/devices/mou
|
|||
RELEASE_flags=-DNDEBUG -O2 -g0 -s
|
||||
DEBUG_flags=-std=c89 -D_POSIX_C_SOURCE=199309L -DDEBUG -Wall -Wno-unknown-pragmas -Wpedantic -Wshadow -Wextra -Werror=implicit-int -Werror=incompatible-pointer-types -Werror=int-conversion -Wvla -g -Og -fsanitize=address -fsanitize=undefined
|
||||
|
||||
.PHONY: all debug dest rom run test install uninstall format clean
|
||||
.PHONY: all debug dest run test install uninstall format clean
|
||||
|
||||
all: dest bin/uxnasm bin/uxncli bin/uxn11
|
||||
|
||||
dest:
|
||||
@ mkdir -p bin
|
||||
rom:
|
||||
@ ./bin/uxnasm etc/screen.bounds.tal bin/res.rom
|
||||
run: all bin/uxnasm bin/uxncli bin/uxn11 rom
|
||||
@ ./bin/uxn11 bin/res.rom
|
||||
run: all bin/uxnasm bin/uxncli bin/uxn11
|
||||
@ ./bin/uxn11
|
||||
test: bin/uxnasm bin/uxncli bin/uxn11
|
||||
@ ./bin/uxnasm && ./bin/uxncli && ./bin/uxn11 && ./bin/uxnasm -v && ./bin/uxncli -v && ./bin/uxn11 -v
|
||||
@ ./bin/uxnasm -v && ./bin/uxncli -v && ./bin/uxn11 -v
|
||||
@ ./bin/uxnasm etc/opctest.tal bin/opctest.rom
|
||||
@ ./bin/uxncli bin/opctest.rom
|
||||
install: bin/uxnasm bin/uxncli bin/uxn11
|
||||
install: all bin/uxnasm bin/uxncli bin/uxn11
|
||||
@ cp bin/uxn11 bin/uxnasm bin/uxncli ~/bin/
|
||||
uninstall:
|
||||
@ rm -f ~/bin/uxn11 ~/bin/uxnasm ~/bin/uxncli
|
||||
format:
|
||||
@ clang-format -i src/uxnasm.c src/uxncli.c src/uxn11.c src/devices/*
|
||||
clean:
|
||||
@ rm -f bin/uxnasm bin/uxncli bin/uxn11 bin/polycat.rom bin/polycat.rom.sym
|
||||
@ rm -fr bin
|
||||
|
||||
bin/uxnasm: src/uxnasm.c
|
||||
@ cc ${RELEASE_flags} ${CFLAGS} src/uxnasm.c -o bin/uxnasm
|
||||
|
|
14
src/uxn11.c
14
src/uxn11.c
|
@ -296,16 +296,14 @@ main(int argc, char **argv)
|
|||
{
|
||||
Uxn u = {0};
|
||||
int i = 1;
|
||||
if(i == argc) {
|
||||
fprintf(stdout, "usage: %s [-v] file.rom [args..]\n", argv[0]);
|
||||
return 0;
|
||||
}
|
||||
if(argv[i][0] == '-' && argv[i][1] == 'v') {
|
||||
fprintf(stdout, "Uxn11 - Varvara Emulator, 14 Feb 2023.\n");
|
||||
char *rom;
|
||||
if(i != argc && argv[i][0] == '-' && argv[i][1] == 'v') {
|
||||
fprintf(stdout, "Uxn11 - Varvara Emulator, 22 Feb 2023.\n");
|
||||
i++;
|
||||
}
|
||||
if(!system_boot(&u, (Uint8 *)calloc(0x10000 * RAM_PAGES, sizeof(Uint8)), argv[i++])) {
|
||||
fprintf(stdout, "Could not boot.\n");
|
||||
rom = i == argc ? "boot.rom" : argv[i++];
|
||||
if(!system_boot(&u, (Uint8 *)calloc(0x10000 * RAM_PAGES, sizeof(Uint8)), rom)) {
|
||||
fprintf(stdout, "usage: %s [-v] file.rom [args..]\n", argv[0]);
|
||||
return 0;
|
||||
}
|
||||
if(!display_init()) {
|
||||
|
|
28
src/uxnasm.c
28
src/uxnasm.c
|
@ -55,6 +55,8 @@ static char ops[][4] = {
|
|||
"ADD", "SUB", "MUL", "DIV", "AND", "ORA", "EOR", "SFT"
|
||||
};
|
||||
|
||||
static char *runes = "|$@&,_.-;=!?#\"%~";
|
||||
|
||||
static int scmp(char *a, char *b, int len) { int i = 0; while(a[i] == b[i]) if(!a[i] || ++i >= len) return 1; return 0; } /* string compare */
|
||||
static int sihx(char *s) { int i = 0; char c; while((c = s[i++])) if(!(c >= '0' && c <= '9') && !(c >= 'a' && c <= 'f')) return 0; return i > 1; } /* string is hexadecimal */
|
||||
static int shex(char *s) { int n = 0, i = 0; char c; while((c = s[i++])) if(c >= '0' && c <= '9') n = n * 16 + (c - '0'); else if(c >= 'a' && c <= 'f') n = n * 16 + 10 + (c - 'a'); return n; } /* string to num */
|
||||
|
@ -156,6 +158,15 @@ makemacro(char *name, FILE *f)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
isrune(char c)
|
||||
{
|
||||
char cc, *r = runes;
|
||||
while((cc = *r++))
|
||||
if(c == cc) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
makelabel(char *name)
|
||||
{
|
||||
|
@ -166,6 +177,8 @@ makelabel(char *name)
|
|||
return error("Label name is hex number", name);
|
||||
if(findopcode(name) || scmp(name, "BRK", 4) || !slen(name))
|
||||
return error("Label name is invalid", name);
|
||||
if(isrune(name[0]))
|
||||
return error("Label name is runic", name);
|
||||
if(p.label_len == 0x400)
|
||||
return error("Labels limit exceeded", name);
|
||||
l = &p.labels[p.label_len++];
|
||||
|
@ -195,7 +208,7 @@ makereference(char *scope, char *label, char rune, Uint16 addr)
|
|||
if(label[0] == '{') {
|
||||
p.lambda_stack[p.lambda_ptr++] = p.lambda_count;
|
||||
scpy(makelambda(p.lambda_count++), r->name, 0x40);
|
||||
} else if(label[0] == '&') {
|
||||
} else if(label[0] == '&' || label[0] == '/') {
|
||||
if(!sublabel(subw, scope, label + 1))
|
||||
return error("Invalid sublabel", label);
|
||||
scpy(subw, r->name, 0x40);
|
||||
|
@ -320,7 +333,10 @@ parse(char *w, FILE *f)
|
|||
case '@': /* label */
|
||||
if(!makelabel(w + 1))
|
||||
return error("Invalid label", w);
|
||||
scpy(w + 1, p.scope, 0x40);
|
||||
i = 0;
|
||||
while(w[i + 1] != '/' && i < 0x3e && (p.scope[i] = w[i + 1]))
|
||||
i++;
|
||||
p.scope[i] = '\0';
|
||||
break;
|
||||
case '&': /* sublabel */
|
||||
if(!sublabel(subw, p.scope, w + 1) || !makelabel(subw))
|
||||
|
@ -346,7 +362,6 @@ parse(char *w, FILE *f)
|
|||
case '.': /* literal byte zero-page */
|
||||
makereference(p.scope, w + 1, w[0], p.ptr + 1);
|
||||
return writelitbyte(0xff);
|
||||
case ':':
|
||||
case '=': /* raw short absolute */
|
||||
makereference(p.scope, w + 1, w[0], p.ptr);
|
||||
return writeshort(0xffff, 0);
|
||||
|
@ -420,7 +435,6 @@ resolve(void)
|
|||
p.data[r->addr] = l->addr & 0xff;
|
||||
l->refs++;
|
||||
break;
|
||||
case ':':
|
||||
case '=':
|
||||
case ';':
|
||||
if(!(l = findlabel(r->name)))
|
||||
|
@ -501,14 +515,12 @@ main(int argc, char *argv[])
|
|||
if(argc == 1)
|
||||
return error("usage", "uxnasm [-v] input.tal output.rom");
|
||||
if(argv[1][0] == '-' && argv[1][1] == 'v')
|
||||
return !fprintf(stdout, "Uxnasm - Uxntal Assembler, 27 Oct 2023.\n");
|
||||
return !fprintf(stdout, "Uxnasm - Uxntal Assembler, 25 Feb 2024.\n");
|
||||
if(!(src = fopen(argv[1], "r")))
|
||||
return !error("Invalid input", argv[1]);
|
||||
if(!assemble(src))
|
||||
return !error("Assembly", "Failed to assemble rom.");
|
||||
if(scmp(argv[2], "-", 2))
|
||||
dst = stdout;
|
||||
else if(!(dst = fopen(argv[2], "wb")))
|
||||
if(!(dst = fopen(argv[2], "wb")))
|
||||
return !error("Invalid Output", argv[2]);
|
||||
if(p.length <= TRIM)
|
||||
return !error("Assembly", "Output rom is empty.");
|
||||
|
|
Loading…
Reference in New Issue