-
Notifications
You must be signed in to change notification settings - Fork 4
/
runlib.fj
168 lines (126 loc) · 4.91 KB
/
runlib.fj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
// w = ?? // memory and operands width. Is defined at compile time.
dw = 2 * w // double word size
dbit = w + #w // the bit-distance from the variable's start, to the bit/hex value (w + dw-width)
// More info about the FlipJump input / output in: https://esolangs.org/wiki/FlipJump#Input_/_Output
ns stl {
// Complexity: 2
// startup Macro - Should be the first piece of code in your program.
// Inits the IO variable, and jumps to the next instruction.
def startup @ code_start {
stl.startup code_start
code_start:
}
// Complexity: 2
// startup Macro - Should be the first piece of code in your program.
// Inits the IO variable, and jumps to the given code start.
// @output-param IO: the address of the opcode that's reserved for Input/Output. More info in https://esolangs.org/wiki/FlipJump#Input_/_Output
def startup code_start > IO {
;code_start // 0w;1w : first code to run
IO:
;0 // 2w;3w : sets the io_handler to address 0 (good for a future wflip)
}
// Complexity: 2.5w+265
// startup Macro - Should be the first piece of code in your program.
// Inits the IO variable, and the pointers globals.
// Jumps to the next instruction.
def startup_and_init_pointers @ code_start {
stl.startup_and_init_pointers code_start
code_start:
}
// Complexity: 2.5w+265
// startup Macro - Should be the first piece of code in your program.
// Inits the IO variable, and the pointers globals.
// Jumps to the given code_start.
def startup_and_init_pointers code_start {
stl.startup code_start
// NOTE: must be placed just after the startup, so that the read_ptr_byte_table will be in address 256.
stl.ptr_init
}
// Complexity: ~7000 (7026 for w=64, 6894 for w=16)
// startup Macro - Should be the first piece of code in your program.
// Initialize anything needed for the standard library.
def startup_and_init_all {
.startup_and_init_all 100
}
// Complexity: 6725 + 2.75w+@ + n
// startup Macro - Should be the first piece of code in your program.
// Initialize anything needed for the standard library.
// stack_bit_size is the size of the global-stack (will hold this number of bits / return-addresses).
def startup_and_init_all stack_bit_size @ code_start {
.startup_and_init_all code_start, stack_bit_size
code_start:
}
// Complexity: 6725 + 2.75w+@ + n
// startup Macro - Should be the first piece of code in your program.
// Initialize anything needed for the standard library.
// stack_bit_size is the size of the global-stack (will hold this number of hexes / return-addresses).
def startup_and_init_all code_start, stack_bit_size {
stl.startup_and_init_pointers code_start
hex.init
stl.stack_init stack_bit_size
}
// ---------- Basic Functionality
// Complexity: 1
// macro for 1 flip-jump op
def fj f, j {
f;j
}
// Complexity: @
// macro for 1 wflip op
def wflip_macro dst, val {
wflip dst, val
}
// Complexity: @
// macro for 1 wflip op (with jump)
def wflip_macro dst, val, jmp_addr {
wflip dst, val, jmp_addr
}
// ---------- Compilation Time Comparisons:
// Complexity: 1
// if expression is 0 (compilation time), jump to l0. else jump to l1
def comp_if expr, l0, l1 {
; expr ? l1 : l0
}
// if expression is 0 (compilation time), jump to l0. else continue
def comp_if0 expr, l0 @ continue {
.comp_if expr, l0, continue
continue:
}
// if expression is not 0 (compilation time), jump to l1. else continue
def comp_if1 expr, l1 @ continue {
.comp_if expr, continue, l1
continue:
}
// if expr != 0 (compilation time), flip the given bit.
//
// expr is a constant, and bit is a general bit-address.
def comp_flip_if bit, expr {
(expr ? bit : 0);
}
// ---------- Unconditional Jumps
// Complexity: 1
// skip the next flip-jump op
def skip {
;$ + dw
}
// finish (loop to self)
def loop {
;$ - dw
}
// ---------- Output constants:
// Complexity: 1
// bit is a constant. 0 will output o, anything else will output 1.
def output_bit bit < .IO {
.IO + (bit ? 1 : 0);
}
// Complexity: 8
// ascii is a constant. The macro outputs the byte (ascii & 0xff)
def output_char ascii {
rep(8, i) .output_bit (ascii>>i)&1
}
// Complexity: 8 * string_length
// str is a constant. The macro outputs the bytes of it (from lsB to msB) until it becomes all zeros.
def output str {
rep(((#str)+7)>>3, i) .output_char (str>>(8*i))&0xff
}
}