Skip to content

Commit a368c0e

Browse files
committed
implement sign extension on all platforms except lua
1 parent 0c843d3 commit a368c0e

File tree

7 files changed

+70
-54
lines changed

7 files changed

+70
-54
lines changed

editors/micro_callisto.yaml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,8 @@ rules:
88
- statement: "\\b(let|enable|requires|struct|version|return|const|enum|restrict)\\b"
99
- statement: "\\b(continue|break|union|alias|overwrite|error|extern|call|raw)\\b"
1010
- statement: "\\b(implement|as|try|catch|throw|unsafe|man|ptr|anon)\\b"
11-
- type: "\\b(addr|void|u8|i8|u16|i16|u32|i32|u64|i64|size|usize|cell|array|bool)\\b"
12-
- type: "\\b[A-Z]+[a-zA-Z_0-9]*[a-z]+[a-zA-Z_0-9]*\\b"
13-
- type: "\\b[A-Z]\\b"
11+
- type: "\\b(addr|void|u8|i8|u16|i16|u32|i32|u64|i64|size|usize|icell|cell|array|bool)\\b"
12+
- type: "\\b[A-Z]+[a-zA-Z_0-9]*[a-z]*[a-zA-Z_0-9]*\\b"
1413

1514
- constant.string:
1615
start: "\""

examples/sierpinski.cal

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,14 @@ func man sierpinski cell n begin
2121
0 -> x
2222

2323
while x n 2 / < do
24-
if x n y 1 + - and then
24+
# x & y
25+
# creates an (upside down) sierpinski triangle, all by itself, that's
26+
# pretty cool
27+
# x & ~y
28+
# this creates a sierpinski triangle too except it's the right way up.
29+
# the not operator flips the whole thing. i think it's interesting how
30+
# bitwise operators can work with a sierpinski triangle so easily
31+
if x y not and then
2532
' ' print_ch
2633
else
2734
'*' print_ch

source/backends/arm64.d

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,10 @@ class BackendARM64 : CompilerBackend {
7070
types ~= Type("u64", 8, false);
7171
types ~= Type("i64", 8, true);
7272
types ~= Type("addr", 8, false);
73-
types ~= Type("size", 8, true);
73+
types ~= Type("isize", 8, true);
7474
types ~= Type("usize", 8, false);
7575
types ~= Type("cell", 8, false);
76+
types ~= Type("icell", 8, true);
7677
types ~= Type("bool", 8, false);
7778

7879
// built in structs

source/backends/lua.d

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,10 @@ class BackendLua : CompilerBackend {
5555

5656
// built in integer types
5757
types ~= Type("addr", 1, false);
58-
types ~= Type("size", 1, true);
58+
types ~= Type("isize", 1, true);
5959
types ~= Type("usize", 1, false);
6060
types ~= Type("cell", 1, false);
61+
types ~= Type("icell", 1, true);
6162
types ~= Type("bool", 1, false);
6263

6364
// built in structs

source/backends/rm86.d

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,10 @@ class BackendRM86 : CompilerBackend {
4646
types ~= Type("u16", 2, false);
4747
types ~= Type("i16", 2, true);
4848
types ~= Type("addr", 2, false);
49-
types ~= Type("size", 2, true);
49+
types ~= Type("isize", 2, true);
5050
types ~= Type("usize", 2, false);
5151
types ~= Type("cell", 2, false);
52+
types ~= Type("icell", 2, true);
5253
types ~= Type("bool", 2, false);
5354

5455
// built in structs
@@ -236,10 +237,6 @@ class BackendRM86 : CompilerBackend {
236237
size = var.type.Size();
237238
}
238239

239-
if (size != 2) {
240-
output ~= "xor ax, ax\n";
241-
}
242-
243240
output ~= "mov di, sp\n";
244241

245242
if (deref) {
@@ -259,6 +256,13 @@ class BackendRM86 : CompilerBackend {
259256
}
260257
}
261258

259+
if ((size == 1) && var.type.isSigned) {
260+
output ~= "cbw\n"; // thank god that exists on 8086
261+
}
262+
else if (size == 1) {
263+
output ~= "xor ah, ah\n";
264+
}
265+
262266
output ~= "mov [si], ax\n";
263267
output ~= "add si, 2\n";
264268
}
@@ -271,10 +275,6 @@ class BackendRM86 : CompilerBackend {
271275
size = var.type.Size();
272276
}
273277

274-
if (size != 2) {
275-
output ~= "xor ax, ax\n";
276-
}
277-
278278
string symbol = format("__global_%s", var.name.Sanitise());
279279

280280
if (deref) {
@@ -294,6 +294,13 @@ class BackendRM86 : CompilerBackend {
294294
}
295295
}
296296

297+
if ((size == 1) && var.type.isSigned) {
298+
output ~= "cbw\n"; // thank god that exists on 8086
299+
}
300+
else if (size == 1) {
301+
output ~= "xor ah, ah\n";
302+
}
303+
297304
output ~= "mov [si], ax\n";
298305
output ~= "add si, 2\n";
299306
}

source/backends/uxn.d

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,10 @@ class BackendUXN : CompilerBackend {
4343
types ~= Type("u16", 2, false);
4444
types ~= Type("i16", 2, true);
4545
types ~= Type("addr", 2, false);
46-
types ~= Type("size", 2, true);
46+
types ~= Type("isize", 2, true);
4747
types ~= Type("usize", 2, false);
4848
types ~= Type("cell", 2, false);
49+
types ~= Type("icell", 2, true);
4950
types ~= Type("bool", 2, false);
5051

5152
// built in structs
@@ -277,7 +278,7 @@ class BackendUXN : CompilerBackend {
277278
}
278279

279280
switch (size) {
280-
case 1: output ~= "LDA NIP\n"; break;
281+
case 1: output ~= "LDA #00 SWP\n"; break;
281282
case 2: output ~= "LDA2\n"; break;
282283
default: Error(node.error, "Bad variable type size");
283284
}
@@ -302,10 +303,17 @@ class BackendUXN : CompilerBackend {
302303
}
303304

304305
switch (size) {
305-
case 1: output ~= "LDA NIP\n"; break;
306+
case 1: output ~= "LDA\n"; break;
306307
case 2: output ~= "LDA2\n"; break;
307308
default: Error(node.error, "Bad variable type size");
308309
}
310+
311+
if ((size == 1) && var.type.isSigned) {
312+
output ~= "LITr 00 LITr ff DUP #80 AND ?{ SWPr } STHr POPr SWP\n";
313+
}
314+
else if (size == 1) {
315+
output ~= "#00 SWP\n";
316+
}
309317
}
310318

311319
override void CompileWord(WordNode node) {

source/backends/x86_64.d

Lines changed: 29 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,10 @@ class BackendX86_64 : CompilerBackend {
8080
types ~= Type("u64", 8, false);
8181
types ~= Type("i64", 8, true);
8282
types ~= Type("addr", 8, false);
83-
types ~= Type("size", 8, true);
83+
types ~= Type("isize", 8, true);
8484
types ~= Type("usize", 8, false);
8585
types ~= Type("cell", 8, false);
86+
types ~= Type("icell", 8, true);
8687
types ~= Type("bool", 8, false);
8788

8889
// built in structs
@@ -534,52 +535,44 @@ class BackendX86_64 : CompilerBackend {
534535
size = var.type.Size();
535536
}
536537

537-
if (size != 8) {
538-
output ~= "xor rax, rax\n";
539-
}
540-
541538
string symbol = format("__global_%s", var.name.Sanitise());
539+
char op = var.type.isSigned? 's' : 'z';
542540

543541
if (deref) {
544542
output ~= format("mov rbx, [%s]\n", symbol);
545-
546-
if (var.type.isSigned) {
547-
switch (size) {
548-
case 1: output ~= format("movsx rax, byte [rbx + %d]\n", offset); break;
549-
case 2: output ~= format("movsx rax, word [rbx + %d]\n", offset); break;
550-
case 4: output ~= format("movsxd rax, dword [rbx + %d]\n", offset); break;
551-
case 8: output ~= format("mov rax, [rbx + %d]\n", offset); break;
552-
default: Error(node.error, "Bad variable type size");
543+
switch (size) {
544+
case 1: {
545+
output ~= format("mov%cx rax, $(BYTE) [rbx + %d]\n", op, offset);
546+
break;
553547
}
554-
}
555-
else {
556-
switch (size) {
557-
case 1: output ~= format("mov al, [rbx + %d]\n", offset); break;
558-
case 2: output ~= format("mov ax, [rbx + %d]\n", offset); break;
559-
case 4: output ~= format("mov eax, [rbx + %d]\n", offset); break;
560-
case 8: output ~= format("mov rax, [rbx + %d]\n", offset); break;
561-
default: Error(node.error, "Bad variable type size");
548+
case 2: {
549+
output ~= format("mov%cx rax, $(WORD) [rbx + %d]\n", op, offset);
550+
break;
551+
}
552+
case 4: {
553+
output ~= format("mov%cxd rax, $(DWORD) [rbx + %d]\n", op, offset);
554+
break;
562555
}
556+
case 8: output ~= format("mov rax, [rbx + %d]\n", offset); break;
557+
default: Error(node.error, "Bad variable type size");
563558
}
564559
}
565560
else {
566-
if (var.type.isSigned) {
567-
switch (size) {
568-
case 1: output ~= format("movsx rax, byte [%s + %d]\n", symbol, offset); break;
569-
case 2: output ~= format("movsx rax, word [%s + %d]\n", symbol, offset); break;
570-
case 4: output ~= format("movsxd rax, dword [%s + %d]\n", symbol, offset); break;
571-
case 8: output ~= format("mov rax, [%s + %d]\n", symbol, offset); break;
572-
default: Error(node.error, "Bad variable type size");
561+
switch (size) {
562+
case 1: {
563+
output ~= format("mov%cx rax, byte [%s + %d]\n", op, symbol, offset);
564+
break;
573565
}
574-
}
575-
else {
576-
switch (size) {
577-
case 1: output ~= format("mov al, [%s + %d]\n", symbol, offset); break;
578-
case 2: output ~= format("mov ax, [%s + %d]\n", symbol, offset); break;
579-
case 4: output ~= format("mov eax, [%s + %d]\n", symbol, offset); break;
580-
case 8: output ~= format("mov rax, [%s + %d]\n", symbol, offset); break;
581-
default: Error(node.error, "Bad variable type size");
566+
case 2: {
567+
output ~= format("mov%cx rax, word [%s + %d]\n", op, symbol, offset);
568+
break;
569+
}
570+
case 4: {
571+
output ~= format("mov%cxd rax, dword [%s + %d]\n", op, symbol, offset);
572+
break;
582573
}
574+
case 8: output ~= format("mov rax, [%s + %d]\n", symbol, offset); break;
575+
default: Error(node.error, "Bad variable type size");
583576
}
584577
}
585578

0 commit comments

Comments
 (0)