compile.sh
· 80 B · Bash
Raw
Playground
#!/usr/bin/env.sh
echo "$1" | nova vm-compile.nv print.nv > program.h
cc main.c
| 1 | #!/usr/bin/env.sh |
| 2 | |
| 3 | echo "$1" | nova vm-compile.nv print.nv > program.h |
| 4 | cc main.c |
main.c
· 2.6 KiB · C
Raw
Playground
#include <limits.h>
#include <stdio.h>
#define STACK_SIZE 10
#define STACK_COUNT 10
#define SIZE_BITS(type) (sizeof(type) * CHAR_BIT)
typedef unsigned int cell;
typedef struct pair pair;
struct pair {
cell first;
cell second;
};
typedef struct stack stack;
struct stack {
cell data[STACK_SIZE];
pair top;
};
typedef struct core core;
struct core {
stack stacks[STACK_COUNT];
cell stack;
};
cell empty(stack *stack) {
return stack->top.first == 0 && stack->top.second == 0;
}
cell full(stack *stack) {
return stack->top.first == STACK_SIZE && stack->top.second == SIZE_BITS(cell);
}
cell peek(stack *stack) {
if(stack == NULL) {
return 0;
}
return stack->data[stack->top.first] & 1;
}
cell pop(stack *stack) {
cell bit = 0;
if(stack == NULL || empty(stack)) {
return 0;
}
bit = peek(stack);
stack->data[stack->top.first] >>= 1;
stack->top.second--;
if(stack->top.second == 0 && stack->top.first != 0) {
stack->top.second = SIZE_BITS(cell);
stack->top.first--;
}
return bit;
}
void push(stack *stack, cell bit) {
if(stack == NULL || full(stack)) {
return;
}
stack->data[stack->top.first] <<= 1;
stack->data[stack->top.first] |= bit;
stack->top.second++;
if(stack->top.second == SIZE_BITS(cell)) {
stack->top.second = 0;
stack->top.first++;
}
return;
}
void print_stack(stack *stack) {
cell iterator = 0;
while(iterator < stack->top.second) {
printf("%d", (stack->data[stack->top.first] >> iterator) & 1);
iterator++;
}
}
void right(core *core) {
core->stack++;
if(core->stack == STACK_COUNT) {
core->stack = 0;
}
}
void left(core *core) {
if(core->stack == 0) {
core->stack = STACK_COUNT;
}
core->stack--;
}
void print_core(core *core) {
cell iterator;
for(iterator = 0; iterator < STACK_COUNT; iterator++) {
if(!empty(&core->stacks[iterator])) {
printf("%d(%d, %d): ", iterator, core->stacks[iterator].top.first, core->stacks[iterator].top.second);
print_stack(&core->stacks[iterator]);
if(iterator == core->stack) {
putchar(" <");
}
putchar("\n");
}
}
}
#define BEGIN while(pop(&c.stacks[c.stack])) {
#define END }
#define LEFT left(&c);
#define RIGHT right(&c);
#define ZERO push(&c.stacks[c.stack], 0);
#define ONE push(&c.stacks[c.stack], 1);
#define HALT return 0;
#define DEBUG print_core(&c);
static core c;
int main(void) {
#include "program.h"
DEBUG
return 0;
}
| 1 | #include <limits.h> |
| 2 | #include <stdio.h> |
| 3 | |
| 4 | #define STACK_SIZE 10 |
| 5 | #define STACK_COUNT 10 |
| 6 | #define SIZE_BITS(type) (sizeof(type) * CHAR_BIT) |
| 7 | typedef unsigned int cell; |
| 8 | |
| 9 | typedef struct pair pair; |
| 10 | struct pair { |
| 11 | cell first; |
| 12 | cell second; |
| 13 | }; |
| 14 | |
| 15 | typedef struct stack stack; |
| 16 | struct stack { |
| 17 | cell data[STACK_SIZE]; |
| 18 | pair top; |
| 19 | }; |
| 20 | |
| 21 | typedef struct core core; |
| 22 | struct core { |
| 23 | stack stacks[STACK_COUNT]; |
| 24 | cell stack; |
| 25 | }; |
| 26 | |
| 27 | cell empty(stack *stack) { |
| 28 | return stack->top.first == 0 && stack->top.second == 0; |
| 29 | } |
| 30 | |
| 31 | cell full(stack *stack) { |
| 32 | return stack->top.first == STACK_SIZE && stack->top.second == SIZE_BITS(cell); |
| 33 | } |
| 34 | |
| 35 | cell peek(stack *stack) { |
| 36 | if(stack == NULL) { |
| 37 | return 0; |
| 38 | } |
| 39 | return stack->data[stack->top.first] & 1; |
| 40 | } |
| 41 | |
| 42 | cell pop(stack *stack) { |
| 43 | cell bit = 0; |
| 44 | if(stack == NULL || empty(stack)) { |
| 45 | return 0; |
| 46 | } |
| 47 | bit = peek(stack); |
| 48 | stack->data[stack->top.first] >>= 1; |
| 49 | stack->top.second--; |
| 50 | if(stack->top.second == 0 && stack->top.first != 0) { |
| 51 | stack->top.second = SIZE_BITS(cell); |
| 52 | stack->top.first--; |
| 53 | } |
| 54 | return bit; |
| 55 | } |
| 56 | |
| 57 | void push(stack *stack, cell bit) { |
| 58 | if(stack == NULL || full(stack)) { |
| 59 | return; |
| 60 | } |
| 61 | stack->data[stack->top.first] <<= 1; |
| 62 | stack->data[stack->top.first] |= bit; |
| 63 | stack->top.second++; |
| 64 | if(stack->top.second == SIZE_BITS(cell)) { |
| 65 | stack->top.second = 0; |
| 66 | stack->top.first++; |
| 67 | } |
| 68 | return; |
| 69 | } |
| 70 | |
| 71 | void print_stack(stack *stack) { |
| 72 | cell iterator = 0; |
| 73 | while(iterator < stack->top.second) { |
| 74 | printf("%d", (stack->data[stack->top.first] >> iterator) & 1); |
| 75 | iterator++; |
| 76 | } |
| 77 | } |
| 78 | |
| 79 | void right(core *core) { |
| 80 | core->stack++; |
| 81 | if(core->stack == STACK_COUNT) { |
| 82 | core->stack = 0; |
| 83 | } |
| 84 | } |
| 85 | |
| 86 | void left(core *core) { |
| 87 | if(core->stack == 0) { |
| 88 | core->stack = STACK_COUNT; |
| 89 | } |
| 90 | core->stack--; |
| 91 | } |
| 92 | |
| 93 | void print_core(core *core) { |
| 94 | cell iterator; |
| 95 | for(iterator = 0; iterator < STACK_COUNT; iterator++) { |
| 96 | if(!empty(&core->stacks[iterator])) { |
| 97 | printf("%d(%d, %d): ", iterator, core->stacks[iterator].top.first, core->stacks[iterator].top.second); |
| 98 | print_stack(&core->stacks[iterator]); |
| 99 | if(iterator == core->stack) { |
| 100 | putchar(" <"); |
| 101 | } |
| 102 | putchar("\n"); |
| 103 | } |
| 104 | } |
| 105 | } |
| 106 | |
| 107 | #define BEGIN while(pop(&c.stacks[c.stack])) { |
| 108 | #define END } |
| 109 | #define LEFT left(&c); |
| 110 | #define RIGHT right(&c); |
| 111 | #define ZERO push(&c.stacks[c.stack], 0); |
| 112 | #define ONE push(&c.stacks[c.stack], 1); |
| 113 | #define HALT return 0; |
| 114 | #define DEBUG print_core(&c); |
| 115 | |
| 116 | static core c; |
| 117 | int main(void) { |
| 118 | #include "program.h" |
| 119 | DEBUG |
| 120 | return 0; |
| 121 | } |
print.nv
· 2.0 KiB · Text
Raw
Playground
|:: print? :string: '%d'| :: print a number
|:: print? :string: '%b'| :: print a number :base: 2
|:: print? :string: '%x'| :: print a number :base: 16
|:: print? :string: '%s'| :: print a string
|:: print? :string: '{}'| :: print an argument
|:: print? :string: '\n'| :string: 10
|:: print? :string: '\t'| :string: 9
|:: print? :string: '\r'| :string: 13
|:: print? :string: '\0'| :string: 0
|:: print? :string: $ | :@stdio: write $
|:: print :string: |
|:: print |
|:: print an argument :arguments: string| :: print a string
|:: print an argument :arguments: number| :: print a number
|:: print an argument :arguments: |
|:: print an argument :arguments: $ | :: error -- unknown argument type $
|:: print a number|
:: convert an argument to a string
:: print an argument
|:: print a string? :arguments: $|:@stdio: write $
|:: print a string :arguments: |
|:: print a string |
|:: convert an argument to a string :arguments: 0|
:arguments: string :arguments:
'0'
:arguments:
|:: convert an argument to a string :arguments: $|
:: break $ into digits
:: make those digits printable
:: push a separator to the arguments stack
:: move those digits to the arguments stack
:: set the argument type to string
|:: break 0 into digits :base: $|
|:: break $number into digits :@rpn.stack: ($next $digit)|
:digits: $digit
:: break $next into digits
|:: break $number into digits? :base: $base?|
:@rpn: ($number $base % $number $base /)
|:: break $number into digits?|
:base: 10
|:: make those digits printable? :@rpn.stack: $| :printable digits: $
|:: make those digits printable? :digits: $| :@rpn: ($ 48 +)
|:: make those digits printable |
|:: push a separator to the arguments stack| :arguments:
|:: move those digits to the arguments stack? :printable digits: $| :arguments: $
|:: move those digits to the arguments stack |
|:: set the argument type to $| :arguments: $
| 1 | |:: print? :string: '%d'| :: print a number |
| 2 | |:: print? :string: '%b'| :: print a number :base: 2 |
| 3 | |:: print? :string: '%x'| :: print a number :base: 16 |
| 4 | |:: print? :string: '%s'| :: print a string |
| 5 | |:: print? :string: '{}'| :: print an argument |
| 6 | |:: print? :string: '\n'| :string: 10 |
| 7 | |:: print? :string: '\t'| :string: 9 |
| 8 | |:: print? :string: '\r'| :string: 13 |
| 9 | |:: print? :string: '\0'| :string: 0 |
| 10 | |:: print? :string: $ | :@stdio: write $ |
| 11 | |:: print :string: | |
| 12 | |:: print | |
| 13 | |
| 14 | |:: print an argument :arguments: string| :: print a string |
| 15 | |:: print an argument :arguments: number| :: print a number |
| 16 | |:: print an argument :arguments: | |
| 17 | |:: print an argument :arguments: $ | :: error -- unknown argument type $ |
| 18 | |
| 19 | |:: print a number| |
| 20 | :: convert an argument to a string |
| 21 | :: print an argument |
| 22 | |
| 23 | |:: print a string? :arguments: $|:@stdio: write $ |
| 24 | |:: print a string :arguments: | |
| 25 | |:: print a string | |
| 26 | |
| 27 | |:: convert an argument to a string :arguments: 0| |
| 28 | :arguments: string :arguments: |
| 29 | '0' |
| 30 | :arguments: |
| 31 | |:: convert an argument to a string :arguments: $| |
| 32 | :: break $ into digits |
| 33 | :: make those digits printable |
| 34 | :: push a separator to the arguments stack |
| 35 | :: move those digits to the arguments stack |
| 36 | :: set the argument type to string |
| 37 | |
| 38 | |:: break 0 into digits :base: $| |
| 39 | |:: break $number into digits :@rpn.stack: ($next $digit)| |
| 40 | :digits: $digit |
| 41 | :: break $next into digits |
| 42 | |:: break $number into digits? :base: $base?| |
| 43 | :@rpn: ($number $base % $number $base /) |
| 44 | |:: break $number into digits?| |
| 45 | :base: 10 |
| 46 | |
| 47 | |:: make those digits printable? :@rpn.stack: $| :printable digits: $ |
| 48 | |:: make those digits printable? :digits: $| :@rpn: ($ 48 +) |
| 49 | |:: make those digits printable | |
| 50 | |
| 51 | |:: push a separator to the arguments stack| :arguments: |
| 52 | |
| 53 | |:: move those digits to the arguments stack? :printable digits: $| :arguments: $ |
| 54 | |:: move those digits to the arguments stack | |
| 55 | |
| 56 | |:: set the argument type to $| :arguments: $ |
vm-compile.nv
· 962 B · Text
Raw
Playground
|:: read a character :@stdio: read|
:end of file:
|:: read a character :@stdio: $x|
:buffer: $x
|:: read a character?|
:@stdio: read
|:: reverse? :buffer: $x|
:text: $x
|:: reverse|
|:: read :end of file|
:: reverse
|:: read?|
:: read a character
|:: parse? :text: ">1<[>[0]<"| :: print :string: " if(pop(&c.stacks[c.stack])) {\n"
|:: parse? :text: ">0<0]>[<" | :: print :string: " } else {\n"
|:: parse? :text: ">0]<" | :: print :string: " }\n"
|:: parse? :text: '0'| :: print :string: " ZERO\n"
|:: parse? :text: '1'| :: print :string: " ONE\n"
|:: parse? :text: '['| :: print :string: " BEGIN\n"
|:: parse? :text: ']'| :: print :string: " END\n"
|:: parse? :text: '<'| :: print :string: " LEFT\n"
|:: parse? :text: '>'| :: print :string: " RIGHT\n"
|:: parse? :text: '@'| :: print :string: " HALT\n"
|:: parse? :text: '?'| :: print :string: " DEBUG\n"
|:: parse? :text: $x |
||:: read :: parse
| 1 | |:: read a character :@stdio: read| |
| 2 | :end of file: |
| 3 | |:: read a character :@stdio: $x| |
| 4 | :buffer: $x |
| 5 | |:: read a character?| |
| 6 | :@stdio: read |
| 7 | |
| 8 | |:: reverse? :buffer: $x| |
| 9 | :text: $x |
| 10 | |:: reverse| |
| 11 | |
| 12 | |:: read :end of file| |
| 13 | :: reverse |
| 14 | |:: read?| |
| 15 | :: read a character |
| 16 | |
| 17 | |:: parse? :text: ">1<[>[0]<"| :: print :string: " if(pop(&c.stacks[c.stack])) {\n" |
| 18 | |:: parse? :text: ">0<0]>[<" | :: print :string: " } else {\n" |
| 19 | |:: parse? :text: ">0]<" | :: print :string: " }\n" |
| 20 | |
| 21 | |:: parse? :text: '0'| :: print :string: " ZERO\n" |
| 22 | |:: parse? :text: '1'| :: print :string: " ONE\n" |
| 23 | |:: parse? :text: '['| :: print :string: " BEGIN\n" |
| 24 | |:: parse? :text: ']'| :: print :string: " END\n" |
| 25 | |:: parse? :text: '<'| :: print :string: " LEFT\n" |
| 26 | |:: parse? :text: '>'| :: print :string: " RIGHT\n" |
| 27 | |:: parse? :text: '@'| :: print :string: " HALT\n" |
| 28 | |:: parse? :text: '?'| :: print :string: " DEBUG\n" |
| 29 | |:: parse? :text: $x | |
| 30 | |
| 31 | ||:: read :: parse |