w: Initial commit
This commit is contained in:
commit
e52878c5e2
5
README.md
Normal file
5
README.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
# ASCII Rendered, Compiled Target Invocation Code
|
||||
|
||||
Like the JVM, but the "binaries" consist of printable ASCII characters and the
|
||||
result can be more easily precompiled for native execution.
|
||||
|
133
doc/documentation.md
Normal file
133
doc/documentation.md
Normal file
|
@ -0,0 +1,133 @@
|
|||
# ASCII Rendered, Compiled Target Invocation Code
|
||||
|
||||
Like the JVM, but the "binaries" consist of printable ASCII characters and the
|
||||
result can be more easily precompiled for native execution.
|
||||
|
||||
## Opcodes
|
||||
|
||||
```{=todo}
|
||||
Notate that immediates can be: …###, …###.###, …$name, or …v (for abcinxyz)
|
||||
for most operations that take immediates.
|
||||
```
|
||||
|
||||
### Summary
|
||||
|
||||
| -0 | -1 | -2 | -3 | -4 | -5 | -6 | -7
|
||||
---:|:------:|:------:|:------:|:------:|:------:|:------:|:------:|:------:
|
||||
000-|`0 BNEZ`|`1 LDAB`|`2 LDAS`|`3 LDAI`|`4 LDAW`|`5 STAB`|`6 STAS`|`7 STAI`
|
||||
001-|`8 STAW`|`9 CASS`|`A PUTA`|`B PUTB`|`C PUTC`|`D MCLR`|`E FTOI`|`F FREE`
|
||||
010-|`G LDOI`|`H LDOS`|`I PUTI`|`J MOFF`|`K MCPY`|`L ROLL`|`M MNEW`|`N PUTN`
|
||||
011-|`O ITOC`|`P PICK`|`Q LDOW`|`R MALL`|`S ITOS`|`T ????`|`U CMPU`|`V B_OR`
|
||||
100-|`W ITOW`|`X PUTX`|`Y PUTY`|`Z PUTZ`|`a GETA`|`b GETB`|`c GETC`|`d MSET`
|
||||
101-|`e SROT`|`f FMOD`|`g FINV`|`h OVER`|`i GETI`|`j FNEG`|`k SPOP`|`l BITC`
|
||||
110-|`m FSUB`|`n GETN`|`o LDOB`|`p FMUL`|`q FDIV`|`r FREM`|`s FADD`|`t SWAP`
|
||||
111-|`u USHR`|`v FABS`|`w SDUP`|`x GETX`|`y GETY`|`z GETZ`|`_ INEG`|`. ITOF`
|
||||
200-|`+ IADD`|`- ISUB`|`* IMUL`|`/ IDIV`|`% IMOD`|`\ IREM`|`| IABS`|`$ VALU`
|
||||
201-|`@ CALL`|`< BLTZ`|`{ BLEZ`|`= BEQZ`|`} BGEZ`|`> BGTZ`|`, JUMP`|`; RTRN`
|
||||
210-|`& BAND`|`^ BXOR`|`! BNOT`|`[ BSHL`|`] BSHR`|`? CMPI`|`~ CMPF`|`: LABL`
|
||||
211-|`( DPTH`|`) PACK`|`' IMP1`|`" IMP2`|`\` BKPT`|`␣ NOP`|`# COMM`|`¶ BEAT`
|
||||
[Operations by code][ops-by-code]
|
||||
|
||||
In this table x, y, and z are integers; a, b, and c are floating point numbers;
|
||||
p and q are memory pointers; and f is a function pointer. Additionally
|
||||
→ indicates a basic operation, while ⇒ indicates an operation using an immediate
|
||||
value, and ↔ indicates a meta operation.
|
||||
|
||||
Code | Stack | Description
|
||||
-----:|:-------------------:|:--------------------------------------------------
|
||||
0 BNEZ| … x ⇒ … | branch to immediate if x not zero
|
||||
1 LDAB| … p → … x | load byte x from p
|
||||
2 LDAS| … p → … x | load short x from p
|
||||
3 LDAI| … p → … x | load int x from p
|
||||
4 LDAW| … p → … x | load word x from p
|
||||
5 STAB| … p x → … | store byte x to p
|
||||
6 STAS| … p x → … | store short x to p
|
||||
7 STAI| … p x → … | store int x to p
|
||||
8 STAW| … p x → … | store word x to p
|
||||
9 CASS| … p x y → … z | compare and swap x and y at p, return success
|
||||
A PUTA| … x → … | store x in rA
|
||||
B PUTB| … x → … | store x in rB
|
||||
C PUTC| … x → … | store x in rC
|
||||
D MCLR| … p x → … | memclear x bytes from p
|
||||
E FTOI| … a → … x | round a to integer and store in x
|
||||
F FREE| … p → … | free memory at p
|
||||
G LDOI| … p ⇒ … x | load int at p plus immediate offset in x
|
||||
H LDOS| … p ⇒ … x | load short at p plus immediate offset in x
|
||||
I PUTI| … x → … | store x in rI
|
||||
J MOFF| … p x → … q | set q to memory pointer p shifted by x bytes
|
||||
K MCPY| … p q x → … | copy x bytes of memory from p to q
|
||||
L ROLL| … x y ‥ z ⇒ … y ‥ z x | roll stack by immediate places
|
||||
M MNEW| … ⇒ … p | allocate memory for immediate bytes at p
|
||||
N PUTN| … x → … | store x in rN
|
||||
O ITOC| … x → … x | truncate x to 8 bits, then sign extend
|
||||
P PICK| … x ‥ z ⇒ … x ‥ z x | pick stack element at immediate place
|
||||
Q LDOW| … p ⇒ … x | load word at p plus immediate offset in x
|
||||
R MALL| … x → … p | allocate memory for x bytes at p
|
||||
S ITOS| … x → … x | truncate x to 16 bits, then sign extend
|
||||
T ????| | reserved for future instruction
|
||||
U CMPU| … x y → … z | compare x to y unsigned and set z such that x o y is z o 0
|
||||
V B_OR| … x y → … z | bitwise OR x and y and store in z
|
||||
W ITOW| … x → … x | truncate x to 32 bits, then sign extend
|
||||
X PUTX| … x → … | store x in rX
|
||||
Y PUTY| … x → … | store x in rY
|
||||
Z PUTZ| … x → … | store x in rZ
|
||||
a GETA| … → … x | load x from rA
|
||||
b GETB| … → … x | load x from rB
|
||||
c GETC| … → … x | load x from rC
|
||||
d MSET| … p x ⇒ … | set x bytes of memory to immediate value at p
|
||||
e SROT| … x y z → … y z x | rotate stack
|
||||
f FMOD| … a b → … c | set c to the modulo of a by b
|
||||
g FINV| … f → f … | invoke f, saving return address on stack
|
||||
h OVER| … x y → … x y x | stack over
|
||||
i GETI| … → … x | load x from rI
|
||||
j FNEG| … a → … a | negate a
|
||||
k SPOP| … x → … | stack pop
|
||||
l BITC| … x y → … z | bit clear y from x to z (z = x and not y)
|
||||
m FSUB| … a b → … c | set c to the difference between a and b (a - b)
|
||||
n GETN| … → … x | load x from rN
|
||||
o LDOB| … p ⇒ … x | load byte at p plus immediate offset in x
|
||||
p FMUL| … a b → … c | set c to the product of a and b
|
||||
q FDIV| … a b → … c | set c to the quotient of a by b
|
||||
r FREM| … a b → … c | set c to the remainder of a by b
|
||||
s FADD| … a b → … c | set c to the sum of a and b
|
||||
t SWAP| … x y → … y x | stack swap
|
||||
u USHR| … x ⇒ … x | logical shift x by immediate bits right
|
||||
v FABS| … a → … a | take the absolute value of a
|
||||
w SDUP| … x → … x x | stack duplicate
|
||||
x GETX| … → … x | load x from rX
|
||||
y GETY| … → … x | load x from rY
|
||||
z GETZ| … → … x | load x from rZ
|
||||
_ INEG| … x → … x | negate x
|
||||
. ITOF| … x → … a | convert x to a floating point number
|
||||
\+ IADD|… x y → … z | set z to the sum of x and y
|
||||
\- ISUB|… x y → … z | set z to the difference between x and y (x - y)
|
||||
\* IMUL|… x y → … z | set z to the product of x and y
|
||||
/ IDIV| … x y → … z | set z to the quotient of x by y
|
||||
% IMOD| … x y → … z | set z to the modulo of x by y
|
||||
\ IREM| … x y → … z | set z to the remainder of x by y
|
||||
\| IABS|… x → … x | take the absolute value of x
|
||||
$ VALU| … ↔ … * | load constant value
|
||||
@ CALL| … ↔ … | call immediate name
|
||||
< BLTZ| … x ⇒ … | branch to immediate if x less than zero
|
||||
{ BLEZ| … x ⇒ … | branch to immediate if x is less than or equal to zero
|
||||
\= BEQZ|… x ⇒ … | branch to immediate if x is zero
|
||||
} BGEZ| … x ⇒ … | branch to immediate if x is greater or equal to zero
|
||||
\> BGTZ|… x ⇒ … | branch to immediate if x is greater than zero
|
||||
, JUMP| … ⇒ … | jump to immediate without pushing return address
|
||||
; RETN| … f ⇒ … | return from subroutine (jump but for stack)
|
||||
& BAND| … x y → … z | set z to the bitwise and of x and y
|
||||
^ BXOR| … x y → … z | set z to the bitwise xor of x and y
|
||||
! BNOT| … x → y | set y to the bitwise not of x
|
||||
[ BSHL| … x ⇒ … x | left shift x by immediate bits
|
||||
] BSHR| … x ⇒ … x | arithmetic right shift x by immediate bits
|
||||
? CMPI| … x y → … z | compare x to y and set z such that x o y is z o 0
|
||||
~ CMPF| … a b ⇒ … c | compare a to b and set c such that a o b is z o c within an immediate error
|
||||
\: LABL|… f ↔ … | label code location
|
||||
( DPTH| … → … x | set x to depth of stack (before x)
|
||||
) PACK| … p x → … | pack x elements of stack (before p) into array p
|
||||
' IMP1| | implementation defined reserved operation 1 (no immediate)
|
||||
" IMP2| | implementation defined reserved operation 2 (immediate)
|
||||
\` BKPT| … ↔ … | trigger breakpoint, or exit if not debugging
|
||||
␣ NOOP| … ↔ … | do nothing, maybe end identifier definition
|
||||
¶ BEAT| … ↔ … | mark a beat for relative branching
|
||||
[Operations in order][ops-in-order]
|
67
src/arctic.c
Normal file
67
src/arctic.c
Normal file
|
@ -0,0 +1,67 @@
|
|||
#include "arctic.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
int arctic_max_expanded_size(int compressed_size) {
|
||||
/* at most every 6th byte is free */
|
||||
return (6 * compressed_size) / 5 + 1;
|
||||
}
|
||||
|
||||
int arctic_max_compressed_size(int expanded_size) {
|
||||
return (5 * expanded_size) / 6 + 1;
|
||||
}
|
||||
|
||||
void arctic_expand(char *expanded, const char *compressed) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void arctic_compress(char *compressed, const char *expanded) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
static const char *parse_immediate(const char *expanded, struct ArcticOperation *op) {
|
||||
return expanded; // TODO
|
||||
}
|
||||
|
||||
void arctic_normalize(struct ArcticOperation *ops, const char *expanded) {
|
||||
const char *o = expanded;
|
||||
struct ArcticOperation *op = ops;
|
||||
|
||||
*op = (struct ArcticOperation){ 0 };
|
||||
|
||||
while (*o) {
|
||||
int opcode = *o++;
|
||||
|
||||
switch (*o) {
|
||||
/* ops with an immediate */
|
||||
case '0': case 'G': case 'H': case 'L': case 'M': case 'P':
|
||||
case 'Q': case 'd': case 'o': case 'u': case '<': case '{':
|
||||
case '=': case '}': case '>': case ',': case ';': case '[':
|
||||
case ']': case '"':
|
||||
o = parse_immediate(o, op);
|
||||
|
||||
/* ops without an immediate */
|
||||
case '1': case '2': case '3': case '4': case '5': case '6':
|
||||
case '7': case '8': case '9': case 'A': case 'B': case 'C':
|
||||
case 'D': case 'E': case 'F': case 'I': case 'J': case 'K':
|
||||
case 'N': case 'O': case 'R': case 'S': case 'U': case 'V':
|
||||
case 'W': case 'X': case 'Y': case 'Z': case 'a': case 'b':
|
||||
case 'c': case 'e': case 'f': case 'g': case 'h': case 'i':
|
||||
case 'j': case 'k': case 'l': case 'm': case 'n': case 'p':
|
||||
case 'q': case 'r': case 's': case 't': case 'v': case 'w':
|
||||
case 'x': case 'y': case 'z': case '_': case '.': case '+':
|
||||
case '-': case '*': case '/': case '%': case '\\': case '|':
|
||||
case '&': case '^': case '!': case '?': case '(': case ')':
|
||||
op->opcode = opcode;
|
||||
*++op = (struct ArcticOperation){ 0 };
|
||||
break;
|
||||
|
||||
/* unusual ops */
|
||||
case '$': case '@': case ':': case '`': case ' ': case '\n':
|
||||
case '\'':
|
||||
|
||||
default: /* non-active characters */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
41
src/arctic.h
Normal file
41
src/arctic.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
/* ARCTIC library header. To be used as a utility by interpreters and compilers.
|
||||
* Author: Louis A. Burke
|
||||
*/
|
||||
#ifndef ARCTIC_H
|
||||
#define ARCTIC_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* encoding/decoding */
|
||||
int arctic_max_expanded_size(int compressed_size);
|
||||
int arctic_max_compressed_size(int expanded_size);
|
||||
void arctic_expand(char *expanded, const char *compressed);
|
||||
void arctic_compress(char *compressed, const char *expanded);
|
||||
|
||||
/* normalization */
|
||||
struct ArcticIdentifier {
|
||||
const char *start; /* a pointer into the input, or null */
|
||||
int length;
|
||||
};
|
||||
|
||||
enum ArcticImmediateKind { ARCTIC_NAME, ARCTIC_INTEGER, ARCTIC_NUMBER };
|
||||
|
||||
struct ArcticImmediate {
|
||||
enum ArcticImmediateKind kind;
|
||||
|
||||
union {
|
||||
struct ArcticIdentifier name;
|
||||
int64_t integer;
|
||||
double number;
|
||||
};
|
||||
};
|
||||
|
||||
struct ArcticOperation {
|
||||
struct ArcticIdentifier label;
|
||||
struct ArcticImmediate immediate;
|
||||
int opcode; /* won't be beat or nop or comm */
|
||||
};
|
||||
|
||||
void arctic_normalize(struct ArcticOperation *ops, const char *expanded);
|
||||
|
||||
#endif /* ARCTIC_H */
|
Loading…
Reference in a new issue