added relative imports

This commit is contained in:
MCorange 2023-04-01 13:20:35 +03:00
parent 747c4e59d4
commit 09bccc8079
13 changed files with 1102 additions and 557 deletions

23
README.md Normal file
View File

@ -0,0 +1,23 @@
# mclang rev2
This is the second revision of [MCLang](https://github.com/mc-lang/mclang) now written in rust!
## Goals
✅ - relatevely usable by normal programmers
✅ - speed comparable to unoptimised C (sometimes)
❌ - static typing
❌ - self hosted (maybe better if not? Since rust is fast asf)
❌ - multiplatform (~~windows~~, linux and mac)
❌ - interop with other languages
❌ - package manager
❌ - installer
## Documentation
The docs are currently are just made in MarkDown.
You can find the docs [here](/docs/index.md)
## Credits
[MCotange](https://github.com/MCorange99) - The one and only me, the creator and current maintainer or mclang rev1 and rev2

2
docs/index.md Normal file
View File

@ -0,0 +1,2 @@
# Docs

View File

@ -0,0 +1,212 @@
# Instructions And Keywords
This explains all of the instructions and keywords
## Instructions
Instructions modify the stack, the stack is an array, i will be using typescript to show how each instruction works
```ts
let stack: number[] = [];
```
### PushInt ("Any Number")
PushInt pushes one number on the stack.
Usage:
```forth
420
```
How it works:
```ts
// num = 420
stack.push(num);
console.assert(stack == [420]);
```
### PushStr ("Any String")
PushStr pushes 2 things on the stack, string length and string pointer
Usage:
```forth
"Henlo world!\n"
```
How it works:
```ts
stack.push(str_len);
stack.push(str_ptr);
```
### Print ("print")
Print just prints a number from the top of the stack into stdout
Usage:
```forth
69 print
```
How it works:
```ts
num = stack.pop()
console.log(num);
```
### Dup ("dup")
Dup duplicates the top most number on the stack
Usage:
```forth
69 dup
```
How it works:
```ts
stack = [12];
a = stack.pop();
stack.push(a);
stack.push(a);
console.assert(stack == [12, 12]);
```
### Drop ("drop")
Drop removes the top most number on the stack
Usage:
```forth
69 drop
```
How it works:
```ts
stack = [69];
stack.pop();
console.assert(stack == []);
```
### Rot ("rot")
Rot moves the third number from the top of the stack and moves it to the top
Usage:
```forth
1 2 3 rot
```
How it works:
```ts
stack = [1, 2, 3];
let a = stack.pop();
let b = stack.pop();
let c = stack.pop();
stack.push(b);
stack.push(a);
stack.push(c);
console.assert(stack == [3, 1, 2]);
```
### Over ("over")
Over takes the second number from the top of the stack and copies it to the top
Usage:
```forth
1 2 over
```
How it works:
```ts
stack = [1, 2];
let a = stack.pop();
let b = stack.pop();
stack.push(b);
stack.push(a);
stack.push(b);
console.assert(stack == [1, 2, 1]);
```
### Swap ("swap")
Swap swaps the first and second numbers from the stack
Usage:
```forth
1 2 stack
```
How it works:
```ts
stack = [1, 2];
let a = stack.pop();
let b = stack.pop();
stack.push(a);
stack.push(b);
console.assert(stack == [2, 1]);
```
### Plus ("+")
### Minus ("-")
### Mul ("*")
### Equals ("=")
### Gt (">")
### Lt ("<")
### NotEquals ("!=")
### Le ("<=")
### Ge (">=")
### Band ("band")
### Bor ("bor")
### Shr ("shr")
### Shl ("shl")
### DivMod ("divmod")
### Mem ("mem")
### Load8 ("@8")
### Store8 ("!8")
### Syscall0 ("syscall0")
### Syscall1 ("syscall1")
### Syscall2 ("syscall2")
### Syscall3 ("syscall3")
### Syscall4 ("syscall4")
### Syscall5 ("syscall5")
### Syscall6 ("syscall6")
### None ("None")
## Keywords
### If ("if")
### Else ("else")
### End ("end")
### While ("while")
### Do ("do")
### Macro ("macro")
### Include ("include")

View File

@ -75,15 +75,18 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
let token = &tokens[ti]; let token = &tokens[ti];
writeln!(writer, "addr_{ti}:")?; writeln!(writer, "addr_{ti}:")?;
match token.typ { match token.typ.clone() {
// stack // stack
OpType::Instruction(InstructionType::PushInt) => {
OpType::Instruction(instruction) => {
match instruction {
InstructionType::PushInt => {
writeln!(writer, " ;; -- push int {}", token.value)?; writeln!(writer, " ;; -- push int {}", token.value)?;
writeln!(writer, " mov rax, {}", token.value)?; writeln!(writer, " mov rax, {}", token.value)?;
writeln!(writer, " push rax")?; writeln!(writer, " push rax")?;
ti += 1; ti += 1;
}, },
OpType::Instruction(InstructionType::PushStr) => { InstructionType::PushStr => {
writeln!(writer, " ;; -- push str \"{}\"", token.text.escape_default())?; writeln!(writer, " ;; -- push str \"{}\"", token.text.escape_default())?;
writeln!(writer, " mov rax, {}", token.text.len())?; writeln!(writer, " mov rax, {}", token.text.len())?;
writeln!(writer, " push rax")?; writeln!(writer, " push rax")?;
@ -91,19 +94,19 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
strings.push(token.text.clone()); strings.push(token.text.clone());
ti += 1; ti += 1;
} }
OpType::Instruction(InstructionType::Drop) => { InstructionType::Drop => {
writeln!(writer, " ;; -- drop")?; writeln!(writer, " ;; -- drop")?;
writeln!(writer, " pop rax")?; writeln!(writer, " pop rax")?;
ti += 1; ti += 1;
}, },
OpType::Instruction(InstructionType::Print) => { InstructionType::Print => {
writeln!(writer, " ;; -- print")?; writeln!(writer, " ;; -- print")?;
writeln!(writer, " pop rdi")?; writeln!(writer, " pop rdi")?;
writeln!(writer, " call print")?; writeln!(writer, " call print")?;
ti += 1; ti += 1;
}, },
OpType::Instruction(InstructionType::Dup) => { InstructionType::Dup => {
writeln!(writer, " ;; -- dup")?; writeln!(writer, " ;; -- dup")?;
writeln!(writer, " pop rax")?; writeln!(writer, " pop rax")?;
writeln!(writer, " push rax")?; writeln!(writer, " push rax")?;
@ -112,7 +115,7 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
ti += 1; ti += 1;
}, },
OpType::Instruction(InstructionType::Rot) => { InstructionType::Rot => {
writeln!(writer, " ;; -- rot")?; writeln!(writer, " ;; -- rot")?;
writeln!(writer, " pop rax")?; writeln!(writer, " pop rax")?;
writeln!(writer, " pop rbx")?; writeln!(writer, " pop rbx")?;
@ -123,7 +126,7 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
ti += 1; ti += 1;
}, },
OpType::Instruction(InstructionType::Swap) => { InstructionType::Swap => {
writeln!(writer, " ;; -- swap")?; writeln!(writer, " ;; -- swap")?;
writeln!(writer, " pop rax")?; writeln!(writer, " pop rax")?;
writeln!(writer, " pop rbx")?; writeln!(writer, " pop rbx")?;
@ -132,7 +135,7 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
ti += 1; ti += 1;
}, },
OpType::Instruction(InstructionType::Over) => { InstructionType::Over => {
writeln!(writer, " ;; -- over")?; writeln!(writer, " ;; -- over")?;
writeln!(writer, " pop rax")?; writeln!(writer, " pop rax")?;
writeln!(writer, " pop rbx")?; writeln!(writer, " pop rbx")?;
@ -144,12 +147,12 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
}, },
//mem //mem
OpType::Instruction(InstructionType::Mem) => { InstructionType::Mem => {
writeln!(writer, " ;; -- mem")?; writeln!(writer, " ;; -- mem")?;
writeln!(writer, " push mem")?; writeln!(writer, " push mem")?;
ti += 1; ti += 1;
} }
OpType::Instruction(InstructionType::Load8) => { InstructionType::Load8 => {
writeln!(writer, " ;; -- load")?; writeln!(writer, " ;; -- load")?;
writeln!(writer, " pop rax")?; writeln!(writer, " pop rax")?;
writeln!(writer, " xor rbx, rbx")?; writeln!(writer, " xor rbx, rbx")?;
@ -158,7 +161,7 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
ti += 1; ti += 1;
} }
OpType::Instruction(InstructionType::Store8) => { InstructionType::Store8 => {
writeln!(writer, " ;; -- store")?; writeln!(writer, " ;; -- store")?;
writeln!(writer, " pop rbx")?; writeln!(writer, " pop rbx")?;
writeln!(writer, " pop rax")?; writeln!(writer, " pop rax")?;
@ -167,7 +170,7 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
} }
// math // math
OpType::Instruction(InstructionType::Plus) => { InstructionType::Plus => {
writeln!(writer, " ;; -- plus")?; writeln!(writer, " ;; -- plus")?;
writeln!(writer, " pop rax")?; writeln!(writer, " pop rax")?;
writeln!(writer, " pop rbx")?; writeln!(writer, " pop rbx")?;
@ -175,7 +178,7 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
writeln!(writer, " push rax")?; writeln!(writer, " push rax")?;
ti += 1; ti += 1;
}, },
OpType::Instruction(InstructionType::Minus) => { InstructionType::Minus => {
writeln!(writer, " ;; -- minus")?; writeln!(writer, " ;; -- minus")?;
writeln!(writer, " pop rax")?; writeln!(writer, " pop rax")?;
writeln!(writer, " pop rbx")?; writeln!(writer, " pop rbx")?;
@ -183,7 +186,7 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
writeln!(writer, " push rbx")?; writeln!(writer, " push rbx")?;
ti += 1; ti += 1;
}, },
OpType::Instruction(InstructionType::Equals) => { InstructionType::Equals => {
writeln!(writer, " ;; -- equals")?; writeln!(writer, " ;; -- equals")?;
writeln!(writer, " mov rcx, 0")?; writeln!(writer, " mov rcx, 0")?;
writeln!(writer, " mov rdx, 1")?; writeln!(writer, " mov rdx, 1")?;
@ -194,7 +197,7 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
writeln!(writer, " push rcx")?; writeln!(writer, " push rcx")?;
ti += 1; ti += 1;
}, },
OpType::Instruction(InstructionType::Lt) => { InstructionType::Lt => {
writeln!(writer, " ;; -- lt")?; writeln!(writer, " ;; -- lt")?;
writeln!(writer, " mov rcx, 0")?; writeln!(writer, " mov rcx, 0")?;
writeln!(writer, " mov rdx, 1")?; writeln!(writer, " mov rdx, 1")?;
@ -205,7 +208,7 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
writeln!(writer, " push rcx")?; writeln!(writer, " push rcx")?;
ti += 1; ti += 1;
}, },
OpType::Instruction(InstructionType::Gt) => { InstructionType::Gt => {
writeln!(writer, " ;; -- gt")?; writeln!(writer, " ;; -- gt")?;
writeln!(writer, " mov rcx, 0")?; writeln!(writer, " mov rcx, 0")?;
writeln!(writer, " mov rdx, 1")?; writeln!(writer, " mov rdx, 1")?;
@ -216,7 +219,7 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
writeln!(writer, " push rcx")?; writeln!(writer, " push rcx")?;
ti += 1; ti += 1;
}, },
OpType::Instruction(InstructionType::NotEquals) => { InstructionType::NotEquals => {
writeln!(writer, " ;; -- not equals")?; writeln!(writer, " ;; -- not equals")?;
writeln!(writer, " mov rcx, 1")?; writeln!(writer, " mov rcx, 1")?;
writeln!(writer, " mov rdx, 0")?; writeln!(writer, " mov rdx, 0")?;
@ -227,7 +230,7 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
writeln!(writer, " push rcx")?; writeln!(writer, " push rcx")?;
ti += 1; ti += 1;
}, },
OpType::Instruction(InstructionType::Le) => { InstructionType::Le => {
writeln!(writer, " ;; -- lt")?; writeln!(writer, " ;; -- lt")?;
writeln!(writer, " mov rcx, 0")?; writeln!(writer, " mov rcx, 0")?;
writeln!(writer, " mov rdx, 1")?; writeln!(writer, " mov rdx, 1")?;
@ -238,7 +241,7 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
writeln!(writer, " push rcx")?; writeln!(writer, " push rcx")?;
ti += 1; ti += 1;
}, },
OpType::Instruction(InstructionType::Ge) => { InstructionType::Ge => {
writeln!(writer, " ;; -- gt")?; writeln!(writer, " ;; -- gt")?;
writeln!(writer, " mov rcx, 0")?; writeln!(writer, " mov rcx, 0")?;
writeln!(writer, " mov rdx, 1")?; writeln!(writer, " mov rdx, 1")?;
@ -249,7 +252,7 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
writeln!(writer, " push rcx")?; writeln!(writer, " push rcx")?;
ti += 1; ti += 1;
}, },
OpType::Instruction(InstructionType::Band) => { InstructionType::Band => {
writeln!(writer, " ;; -- band")?; writeln!(writer, " ;; -- band")?;
writeln!(writer, " pop rax")?; writeln!(writer, " pop rax")?;
writeln!(writer, " pop rbx")?; writeln!(writer, " pop rbx")?;
@ -257,7 +260,7 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
writeln!(writer, " push rbx")?; writeln!(writer, " push rbx")?;
ti += 1; ti += 1;
}, },
OpType::Instruction(InstructionType::Bor) => { InstructionType::Bor => {
writeln!(writer, " ;; -- bor")?; writeln!(writer, " ;; -- bor")?;
writeln!(writer, " pop rax")?; writeln!(writer, " pop rax")?;
writeln!(writer, " pop rbx")?; writeln!(writer, " pop rbx")?;
@ -265,7 +268,7 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
writeln!(writer, " push rbx")?; writeln!(writer, " push rbx")?;
ti += 1; ti += 1;
}, },
OpType::Instruction(InstructionType::Shr) => { InstructionType::Shr => {
writeln!(writer, " ;; -- shr")?; writeln!(writer, " ;; -- shr")?;
writeln!(writer, " pop rcx")?; writeln!(writer, " pop rcx")?;
writeln!(writer, " pop rbx")?; writeln!(writer, " pop rbx")?;
@ -273,7 +276,7 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
writeln!(writer, " push rbx")?; writeln!(writer, " push rbx")?;
ti += 1; ti += 1;
}, },
OpType::Instruction(InstructionType::Shl) => { InstructionType::Shl => {
writeln!(writer, " ;; -- shl")?; writeln!(writer, " ;; -- shl")?;
writeln!(writer, " pop rcx")?; writeln!(writer, " pop rcx")?;
writeln!(writer, " pop rbx")?; writeln!(writer, " pop rbx")?;
@ -281,7 +284,7 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
writeln!(writer, " push rbx")?; writeln!(writer, " push rbx")?;
ti += 1; ti += 1;
}, },
OpType::Instruction(InstructionType::DivMod) => { InstructionType::DivMod => {
writeln!(writer, " ;; -- div")?; writeln!(writer, " ;; -- div")?;
writeln!(writer, " xor rdx, rdx")?; writeln!(writer, " xor rdx, rdx")?;
writeln!(writer, " pop rbx")?; writeln!(writer, " pop rbx")?;
@ -291,7 +294,7 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
writeln!(writer, " push rdx")?; writeln!(writer, " push rdx")?;
ti += 1; ti += 1;
}, },
OpType::Instruction(InstructionType::Mul) => { InstructionType::Mul => {
writeln!(writer, " ;; -- mul")?; writeln!(writer, " ;; -- mul")?;
writeln!(writer, " pop rax")?; writeln!(writer, " pop rax")?;
writeln!(writer, " pop rbx")?; writeln!(writer, " pop rbx")?;
@ -299,47 +302,14 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
writeln!(writer, " push rax")?; writeln!(writer, " push rax")?;
ti += 1; ti += 1;
}, },
InstructionType::Syscall0 => {
// block
OpType::Keyword(KeywordType::If) => {
writeln!(writer, " ;; -- if")?;
writeln!(writer, " pop rax")?;
writeln!(writer, " test rax, rax")?;
writeln!(writer, " jz addr_{}", token.jmp)?;
ti += 1;
},
OpType::Keyword(KeywordType::Else) => {
writeln!(writer, " ;; -- else")?;
writeln!(writer, " jmp addr_{}", token.jmp)?;
ti += 1;
},
OpType::Keyword(KeywordType::While) => {
writeln!(writer, " ;; -- while")?;
ti += 1;
}
OpType::Keyword(KeywordType::Do) => {
writeln!(writer, " ;; -- do")?;
writeln!(writer, " pop rax")?;
writeln!(writer, " test rax, rax")?;
writeln!(writer, " jz addr_{}", token.jmp)?;
ti += 1;
}
OpType::Keyword(KeywordType::End) => {
writeln!(writer, " ;; -- end")?;
if ti + 1 != token.jmp {
writeln!(writer, " jmp addr_{}", token.jmp)?;
}
ti += 1;
},
OpType::Instruction(InstructionType::Syscall0) => {
writeln!(writer, " ;; -- syscall0")?; writeln!(writer, " ;; -- syscall0")?;
writeln!(writer, " pop rax")?; writeln!(writer, " pop rax")?;
writeln!(writer, " syscall")?; writeln!(writer, " syscall")?;
writeln!(writer, " push rax")?; writeln!(writer, " push rax")?;
ti += 1; ti += 1;
}, },
OpType::Instruction(InstructionType::Syscall1) => { InstructionType::Syscall1 => {
writeln!(writer, " ;; -- syscall1")?; writeln!(writer, " ;; -- syscall1")?;
writeln!(writer, " pop rax")?; writeln!(writer, " pop rax")?;
writeln!(writer, " pop rdi")?; writeln!(writer, " pop rdi")?;
@ -347,7 +317,7 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
writeln!(writer, " push rax")?; writeln!(writer, " push rax")?;
ti += 1; ti += 1;
}, },
OpType::Instruction(InstructionType::Syscall2) => { InstructionType::Syscall2 => {
writeln!(writer, " ;; -- syscall2")?; writeln!(writer, " ;; -- syscall2")?;
writeln!(writer, " pop rax")?; writeln!(writer, " pop rax")?;
writeln!(writer, " pop rdi")?; writeln!(writer, " pop rdi")?;
@ -356,7 +326,7 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
writeln!(writer, " push rax")?; writeln!(writer, " push rax")?;
ti += 1; ti += 1;
}, },
OpType::Instruction(InstructionType::Syscall3) => { InstructionType::Syscall3 => {
writeln!(writer, " ;; -- syscall3")?; writeln!(writer, " ;; -- syscall3")?;
writeln!(writer, " pop rax")?; writeln!(writer, " pop rax")?;
writeln!(writer, " pop rdi")?; writeln!(writer, " pop rdi")?;
@ -367,7 +337,7 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
ti += 1; ti += 1;
}, },
OpType::Instruction(InstructionType::Syscall4) => { InstructionType::Syscall4 => {
writeln!(writer, " ;; -- syscall4")?; writeln!(writer, " ;; -- syscall4")?;
writeln!(writer, " pop rax")?; writeln!(writer, " pop rax")?;
writeln!(writer, " pop rdi")?; writeln!(writer, " pop rdi")?;
@ -378,7 +348,7 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
writeln!(writer, " push rax")?; writeln!(writer, " push rax")?;
ti += 1; ti += 1;
}, },
OpType::Instruction(InstructionType::Syscall5) => { InstructionType::Syscall5 => {
writeln!(writer, " ;; -- syscall5")?; writeln!(writer, " ;; -- syscall5")?;
writeln!(writer, " pop rax")?; writeln!(writer, " pop rax")?;
writeln!(writer, " pop rdi")?; writeln!(writer, " pop rdi")?;
@ -390,7 +360,7 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
writeln!(writer, " push rax")?; writeln!(writer, " push rax")?;
ti += 1; ti += 1;
}, },
OpType::Instruction(InstructionType::Syscall6) => { InstructionType::Syscall6 => {
writeln!(writer, " ;; -- syscall6")?; writeln!(writer, " ;; -- syscall6")?;
writeln!(writer, " pop rax")?; writeln!(writer, " pop rax")?;
writeln!(writer, " pop rdi")?; writeln!(writer, " pop rdi")?;
@ -403,7 +373,53 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
writeln!(writer, " push rax")?; writeln!(writer, " push rax")?;
ti += 1; ti += 1;
}, },
OpType::Instruction(InstructionType::None) | OpType::Keyword(KeywordType::Macro) | OpType::Keyword(KeywordType::Include) => unreachable!() InstructionType::None => unreachable!(),
InstructionType::CastBool => ti += 1,
InstructionType::CastPtr => ti += 1,
InstructionType::CastInt => ti += 1,
}
}
OpType::Keyword(keyword) => {
match keyword {
// block
KeywordType::If => {
writeln!(writer, " ;; -- if")?;
writeln!(writer, " pop rax")?;
writeln!(writer, " test rax, rax")?;
writeln!(writer, " jz addr_{}", token.jmp)?;
ti += 1;
},
KeywordType::Else => {
writeln!(writer, " ;; -- else")?;
writeln!(writer, " jmp addr_{}", token.jmp)?;
ti += 1;
},
KeywordType::While => {
writeln!(writer, " ;; -- while")?;
ti += 1;
}
KeywordType::Do => {
writeln!(writer, " ;; -- do")?;
writeln!(writer, " pop rax")?;
writeln!(writer, " test rax, rax")?;
writeln!(writer, " jz addr_{}", token.jmp)?;
ti += 1;
}
KeywordType::End => {
writeln!(writer, " ;; -- end")?;
if ti + 1 != token.jmp {
writeln!(writer, " jmp addr_{}", token.jmp)?;
}
ti += 1;
},
KeywordType::Macro |
KeywordType::Include
=> unreachable!()
}
}
} }
} }
writeln!(writer, "addr_{ti}:")?; writeln!(writer, "addr_{ti}:")?;
@ -411,10 +427,10 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
writeln!(writer, " mov rdi, 0")?; writeln!(writer, " mov rdi, 0")?;
writeln!(writer, " syscall")?; writeln!(writer, " syscall")?;
writeln!(writer, "segment .data")?; writeln!(writer, "segment .data")?;
for (_, s) in strings.iter().enumerate() { for (i, s) in strings.iter().enumerate() {
let s_chars = s.chars().map(|c| (c as u32).to_string()).collect::<Vec<String>>(); let s_chars = s.chars().map(|c| (c as u32).to_string()).collect::<Vec<String>>();
let s_list = s_chars.join(","); let s_list = s_chars.join(",");
writeln!(writer, " str_{}: db {} ; {}", s, s_list, s.escape_default())?; writeln!(writer, " str_{}: db {} ; {}", i, s_list, s.escape_default())?;
} }
writeln!(writer, "segment .bss")?; writeln!(writer, "segment .bss")?;

View File

@ -46,6 +46,10 @@ pub enum InstructionType {
Syscall5, Syscall5,
Syscall6, Syscall6,
CastBool,
CastPtr,
CastInt,
None // Used for macros and any other non built in word definitions None // Used for macros and any other non built in word definitions
} }
@ -132,7 +136,10 @@ impl OpType {
OpType::Instruction(InstructionType::Syscall4) => "syscall4", OpType::Instruction(InstructionType::Syscall4) => "syscall4",
OpType::Instruction(InstructionType::Syscall5) => "syscall5", OpType::Instruction(InstructionType::Syscall5) => "syscall5",
OpType::Instruction(InstructionType::Syscall6) => "syscall6", OpType::Instruction(InstructionType::Syscall6) => "syscall6",
OpType::Instruction(InstructionType::None) => "None" OpType::Instruction(InstructionType::CastBool) => "cast(bool",
OpType::Instruction(InstructionType::CastPtr) => "cast(ptr)",
OpType::Instruction(InstructionType::CastInt) => "cast(int)",
OpType::Instruction(InstructionType::None) => "None",
}.to_string() }.to_string()
} }
} }
@ -176,3 +183,17 @@ impl TokenType {
} }
pub type Loc = (String, usize, usize); pub type Loc = (String, usize, usize);
#[derive(Debug, PartialEq, Clone)]
pub enum Types {
Bool,
Ptr,
Int,
Any
// U8,
// U16,
// U32,
// U64,
// todo: add signed numbers since we dont have them yet lol
}

View File

@ -24,14 +24,14 @@ pub fn run(tokens: &[crate::constants::Operator]) -> Result<i32>{
let token = &tokens[ti]; let token = &tokens[ti];
let pos = token.loc.clone(); let pos = token.loc.clone();
// println!("{:?}", token.typ); // println!("{:?}", token.typ);
match token.typ { match token.typ.clone() {
OpType::Instruction(instruction) => {
// stack match instruction {
OpType::Instruction(InstructionType::PushInt) => { InstructionType::PushInt => {
stack.push(token.value); stack.push(token.value);
ti += 1; ti += 1;
}, },
OpType::Instruction(InstructionType::PushStr) => { InstructionType::PushStr => {
if token.addr.is_none() { if token.addr.is_none() {
stack.push(token.text.len()); // string len stack.push(token.text.len()); // string len
stack.push(string_idx + crate::compile::MEM_SZ); stack.push(string_idx + crate::compile::MEM_SZ);
@ -50,18 +50,18 @@ pub fn run(tokens: &[crate::constants::Operator]) -> Result<i32>{
ti += 1; ti += 1;
}, },
OpType::Instruction(InstructionType::Drop) => { InstructionType::Drop => {
stack.pop(); stack.pop();
ti += 1; ti += 1;
}, },
OpType::Instruction(InstructionType::Dup) => { InstructionType::Dup => {
let a = stack_pop(&mut stack, &pos)?; let a = stack_pop(&mut stack, &pos)?;
stack.push(a); stack.push(a);
stack.push(a); stack.push(a);
ti += 1; ti += 1;
}, },
OpType::Instruction(InstructionType::Rot) => { InstructionType::Rot => {
let a = stack_pop(&mut stack, &pos)?; let a = stack_pop(&mut stack, &pos)?;
let b = stack_pop(&mut stack, &pos)?; let b = stack_pop(&mut stack, &pos)?;
let c = stack_pop(&mut stack, &pos)?; let c = stack_pop(&mut stack, &pos)?;
@ -70,14 +70,14 @@ pub fn run(tokens: &[crate::constants::Operator]) -> Result<i32>{
stack.push(c); stack.push(c);
ti += 1; ti += 1;
} }
OpType::Instruction(InstructionType::Swap) => { InstructionType::Swap => {
let a = stack_pop(&mut stack, &pos)?; let a = stack_pop(&mut stack, &pos)?;
let b = stack_pop(&mut stack, &pos)?; let b = stack_pop(&mut stack, &pos)?;
stack.push(a); stack.push(a);
stack.push(b); stack.push(b);
ti += 1; ti += 1;
} }
OpType::Instruction(InstructionType::Over) => { InstructionType::Over => {
let a = stack_pop(&mut stack, &pos)?; let a = stack_pop(&mut stack, &pos)?;
let b = stack_pop(&mut stack, &pos)?; let b = stack_pop(&mut stack, &pos)?;
stack.push(b); stack.push(b);
@ -86,7 +86,7 @@ pub fn run(tokens: &[crate::constants::Operator]) -> Result<i32>{
ti += 1; ti += 1;
} }
OpType::Instruction(InstructionType::Print) => { InstructionType::Print => {
let a = stack_pop(&mut stack, &pos)?; let a = stack_pop(&mut stack, &pos)?;
println!("{a}"); println!("{a}");
// let _ = io::stdout().flush(); // let _ = io::stdout().flush();
@ -94,18 +94,18 @@ pub fn run(tokens: &[crate::constants::Operator]) -> Result<i32>{
}, },
// mem // mem
OpType::Instruction(InstructionType::Mem) => { InstructionType::Mem => {
stack.push(0); stack.push(0);
ti += 1; ti += 1;
} }
OpType::Instruction(InstructionType::Load8) => { InstructionType::Load8 => {
let a = stack_pop(&mut stack, &pos)?; let a = stack_pop(&mut stack, &pos)?;
let byte = mem[a]; let byte = mem[a];
stack.push(byte as usize); stack.push(byte as usize);
ti += 1; ti += 1;
} }
#[allow(clippy::cast_possible_truncation)] #[allow(clippy::cast_possible_truncation)]
OpType::Instruction(InstructionType::Store8) => { InstructionType::Store8 => {
let val = stack_pop(&mut stack, &pos)?; let val = stack_pop(&mut stack, &pos)?;
let addr = stack_pop(&mut stack, &pos)?; let addr = stack_pop(&mut stack, &pos)?;
@ -114,97 +114,145 @@ pub fn run(tokens: &[crate::constants::Operator]) -> Result<i32>{
} }
// math // math
OpType::Instruction(InstructionType::Plus) => { InstructionType::Plus => {
let a = stack_pop(&mut stack, &pos)?; let a = stack_pop(&mut stack, &pos)?;
let b = stack_pop(&mut stack, &pos)?; let b = stack_pop(&mut stack, &pos)?;
stack.push(b + a); stack.push(b + a);
ti += 1; ti += 1;
}, },
OpType::Instruction(InstructionType::Minus) => { InstructionType::Minus => {
let a = stack_pop(&mut stack, &pos)?; let a = stack_pop(&mut stack, &pos)?;
let b = stack_pop(&mut stack, &pos)?; let b = stack_pop(&mut stack, &pos)?;
stack.push(b - a); stack.push(b - a);
ti += 1; ti += 1;
}, },
OpType::Instruction(InstructionType::Equals) => { InstructionType::Equals => {
let a = stack_pop(&mut stack, &pos)?; let a = stack_pop(&mut stack, &pos)?;
let b = stack_pop(&mut stack, &pos)?; let b = stack_pop(&mut stack, &pos)?;
stack.push(usize::from(b == a)); stack.push(usize::from(b == a));
ti += 1; ti += 1;
}, },
OpType::Instruction(InstructionType::Gt) => { InstructionType::Gt => {
let a = stack_pop(&mut stack, &pos)?; let a = stack_pop(&mut stack, &pos)?;
let b = stack_pop(&mut stack, &pos)?; let b = stack_pop(&mut stack, &pos)?;
stack.push(usize::from(b > a)); stack.push(usize::from(b > a));
ti += 1; ti += 1;
}, },
OpType::Instruction(InstructionType::Lt) => { InstructionType::Lt => {
let a = stack_pop(&mut stack, &pos)?; let a = stack_pop(&mut stack, &pos)?;
let b = stack_pop(&mut stack, &pos)?; let b = stack_pop(&mut stack, &pos)?;
stack.push(usize::from(b < a)); stack.push(usize::from(b < a));
ti += 1; ti += 1;
}, },
OpType::Instruction(InstructionType::NotEquals) => { InstructionType::NotEquals => {
let a = stack_pop(&mut stack, &pos)?; let a = stack_pop(&mut stack, &pos)?;
let b = stack_pop(&mut stack, &pos)?; let b = stack_pop(&mut stack, &pos)?;
stack.push(usize::from(b != a)); stack.push(usize::from(b != a));
ti += 1; ti += 1;
}, },
OpType::Instruction(InstructionType::Ge) => { InstructionType::Ge => {
let a = stack_pop(&mut stack, &pos)?; let a = stack_pop(&mut stack, &pos)?;
let b = stack_pop(&mut stack, &pos)?; let b = stack_pop(&mut stack, &pos)?;
stack.push(usize::from(b >= a)); stack.push(usize::from(b >= a));
ti += 1; ti += 1;
}, },
OpType::Instruction(InstructionType::Le) => { InstructionType::Le => {
let a = stack_pop(&mut stack, &pos)?; let a = stack_pop(&mut stack, &pos)?;
let b = stack_pop(&mut stack, &pos)?; let b = stack_pop(&mut stack, &pos)?;
stack.push(usize::from(b <= a)); stack.push(usize::from(b <= a));
ti += 1; ti += 1;
}, },
OpType::Instruction(InstructionType::Band) => { InstructionType::Band => {
let a = stack_pop(&mut stack, &pos)?; let a = stack_pop(&mut stack, &pos)?;
let b = stack_pop(&mut stack, &pos)?; let b = stack_pop(&mut stack, &pos)?;
stack.push(a & b); stack.push(a & b);
ti += 1; ti += 1;
} }
OpType::Instruction(InstructionType::Bor) => { InstructionType::Bor => {
let a = stack_pop(&mut stack, &pos)?; let a = stack_pop(&mut stack, &pos)?;
let b = stack_pop(&mut stack, &pos)?; let b = stack_pop(&mut stack, &pos)?;
stack.push(a | b); stack.push(a | b);
ti += 1; ti += 1;
} }
OpType::Instruction(InstructionType::Shr) => { InstructionType::Shr => {
let a = stack_pop(&mut stack, &pos)?; let a = stack_pop(&mut stack, &pos)?;
let b = stack_pop(&mut stack, &pos)?; let b = stack_pop(&mut stack, &pos)?;
stack.push(b >> a); stack.push(b >> a);
ti += 1; ti += 1;
} }
OpType::Instruction(InstructionType::Shl) => { InstructionType::Shl => {
let a = stack_pop(&mut stack, &pos)?; let a = stack_pop(&mut stack, &pos)?;
let b = stack_pop(&mut stack, &pos)?; let b = stack_pop(&mut stack, &pos)?;
stack.push(b << a); stack.push(b << a);
ti += 1; ti += 1;
} }
OpType::Instruction(InstructionType::DivMod) => { InstructionType::DivMod => {
let a = stack_pop(&mut stack, &pos)?; let a = stack_pop(&mut stack, &pos)?;
let b = stack_pop(&mut stack, &pos)?; let b = stack_pop(&mut stack, &pos)?;
stack.push(b / a); stack.push(b / a);
stack.push(b % a); stack.push(b % a);
ti += 1; ti += 1;
} }
OpType::Instruction(InstructionType::Mul) => { InstructionType::Mul => {
let a = stack_pop(&mut stack, &pos)?; let a = stack_pop(&mut stack, &pos)?;
let b = stack_pop(&mut stack, &pos)?; let b = stack_pop(&mut stack, &pos)?;
stack.push(b * a); stack.push(b * a);
ti += 1; ti += 1;
} }
InstructionType::Syscall0 => {
todo!();
// ti += 1;
},
InstructionType::Syscall1 => {
todo!();
// ti += 1;
},
InstructionType::Syscall2 => {
todo!();
// ti += 1;
},
InstructionType::Syscall3 => {
let rax = stack_pop(&mut stack, &pos)?;
let rdi = stack_pop(&mut stack, &pos)?;
let rsi = stack_pop(&mut stack, &pos)?;
let rdx = stack_pop(&mut stack, &pos)?;
// println!("yes");
let ret = match rax {
1 => syscalls::sys_write(rax, rdi, rsi, rdx, &mem),
0 => 0, //? temp, so clippy doesnt complain
_ => {
error!("Syscall(3) #{} is not implemented", rax);
return Err(eyre!("Syscall not implemented"));
}
};
stack.push(ret);
// println!("{}", stack.len());
ti += 1;
},
InstructionType::Syscall4 => {
todo!();
// ti += 1;
},
InstructionType::Syscall5 => {
todo!();
// ti += 1;
},
InstructionType::Syscall6 => {
todo!();
// ti += 1;
},
InstructionType::CastBool => ti += 1,
InstructionType::CastPtr => ti += 1,
InstructionType::CastInt => ti += 1,
InstructionType::None => unreachable!()
}
}
// blocks // blocks
OpType::Keyword(KeywordType::If) => { OpType::Keyword(KeywordType::If) => {
@ -230,49 +278,7 @@ pub fn run(tokens: &[crate::constants::Operator]) -> Result<i32>{
ti += 1; ti += 1;
} }
} }
OpType::Instruction(InstructionType::Syscall0) => { | OpType::Keyword(KeywordType::Macro) | OpType::Keyword(KeywordType::Include) => unreachable!()
todo!();
// ti += 1;
},
OpType::Instruction(InstructionType::Syscall1) => {
todo!();
// ti += 1;
},
OpType::Instruction(InstructionType::Syscall2) => {
todo!();
// ti += 1;
},
OpType::Instruction(InstructionType::Syscall3) => {
let rax = stack_pop(&mut stack, &pos)?;
let rdi = stack_pop(&mut stack, &pos)?;
let rsi = stack_pop(&mut stack, &pos)?;
let rdx = stack_pop(&mut stack, &pos)?;
// println!("yes");
let ret = match rax {
1 => syscalls::sys_write(rax, rdi, rsi, rdx, &mem),
0 => 0, //? temp, so clippy doesnt complain
_ => {
error!("Syscall(3) #{} is not implemented", rax);
return Err(eyre!("Syscall not implemented"));
}
};
stack.push(ret);
// println!("{}", stack.len());
ti += 1;
},
OpType::Instruction(InstructionType::Syscall4) => {
todo!();
// ti += 1;
},
OpType::Instruction(InstructionType::Syscall5) => {
todo!();
// ti += 1;
},
OpType::Instruction(InstructionType::Syscall6) => {
todo!();
// ti += 1;
},
OpType::Instruction(InstructionType::None) | OpType::Keyword(KeywordType::Macro) | OpType::Keyword(KeywordType::Include) => unreachable!()
} }
} }

View File

@ -5,6 +5,7 @@ mod compile;
mod parser; mod parser;
mod lexer; mod lexer;
mod preprocessor; mod preprocessor;
mod typechecker;
use std::fs; use std::fs;
@ -54,6 +55,8 @@ pub struct Args {
} }
fn main() { fn main() {
let args = Args::parse(); let args = Args::parse();
let Ok(code) = fs::read_to_string(&args.in_file) else { let Ok(code) = fs::read_to_string(&args.in_file) else {
@ -73,6 +76,11 @@ fn main() {
return; return;
}; };
let Ok(tokens) = typechecker::typecheck(&tokens, &args) else {
error!("Typechecking failed, exiting!");
return;
};
let c = if args.compile && args.interpret { let c = if args.compile && args.interpret {
error!("Cannot compile and interpret at the same time"); error!("Cannot compile and interpret at the same time");
0 0

View File

@ -156,6 +156,9 @@ pub fn lookup_word<P: Deref<Target = Loc>>(s: &str, _pos: P) -> OpType {
"syscall4" => OpType::Instruction(InstructionType::Syscall4), "syscall4" => OpType::Instruction(InstructionType::Syscall4),
"syscall5" => OpType::Instruction(InstructionType::Syscall5), "syscall5" => OpType::Instruction(InstructionType::Syscall5),
"syscall6" => OpType::Instruction(InstructionType::Syscall6), "syscall6" => OpType::Instruction(InstructionType::Syscall6),
"cast(bool" => OpType::Instruction(InstructionType::CastBool),
"cast(ptr)" => OpType::Instruction(InstructionType::CastPtr),
"cast(int)" => OpType::Instruction(InstructionType::CastInt),
_ => OpType::Instruction(InstructionType::None) _ => OpType::Instruction(InstructionType::None)
} }

View File

@ -1,5 +1,5 @@
use std::collections::HashMap; use std::collections::HashMap;
use std::path::PathBuf; use std::path::{PathBuf, Path};
use color_eyre::Result; use color_eyre::Result;
use eyre::eyre; use eyre::eyre;
@ -93,18 +93,25 @@ pub fn preprocess(tokens: Vec<Token>, args: &Args) -> Result<Vec<Token>>{
let mut include_code = String::new(); let mut include_code = String::new();
if include_path.text.chars().collect::<Vec<char>>()[0] == '.' {
let p = Path::new(include_path.file.as_str());
let p = p.parent().unwrap();
let p = p.join(&include_path.text);
include_code = std::fs::read_to_string(p)?;
} else {
for path in in_paths { for path in in_paths {
let p = PathBuf::from(path); let p = PathBuf::from(path);
let p = p.join(include_path.text.clone()); let p = p.join(&include_path.text);
if p.exists() { if p.exists() {
include_code = std::fs::read_to_string(p)?; include_code = std::fs::read_to_string(p)?;
} }
} }
}
if include_code.is_empty() { if include_code.is_empty() {
lerror!(&include_path.loc(), "Include file in path '{}' was not found", include_path.text); lerror!(&include_path.loc(), "Include file in path '{}' was not found or is empty", include_path.text);
return Err(eyre!("")); return Err(eyre!(""));
} }

245
src/typechecker.rs Normal file
View File

@ -0,0 +1,245 @@
use crate::{constants::{Operator, Types, OpType, KeywordType, InstructionType}, Args, lerror};
use color_eyre::Result;
use eyre::eyre;
pub fn typecheck(ops: &[Operator], args: &Args) -> Result<Vec<Operator>>{
let mut stack: Vec<Types> = Vec::new();
for op in ops {
match op.typ.clone() {
OpType::Keyword(keyword) => {
match keyword {
KeywordType::If => {
stack_pop(&mut stack, &op, &[Types::Bool])?;
},
KeywordType::Else => {
},
KeywordType::End => {
},
KeywordType::While => {
},
KeywordType::Do => {
stack_pop(&mut stack, &op, &[Types::Bool])?;
},
KeywordType::Macro => {
},
KeywordType::Include => {
},
}
},
OpType::Instruction(instruction) => {
match instruction {
InstructionType::PushInt => {
stack.push(Types::Int);
},
InstructionType::PushStr => {
stack.push(Types::Int);
stack.push(Types::Ptr);
},
InstructionType::Drop => {
stack_pop(&mut stack, &op, &[Types::Any])?;
},
InstructionType::Print => {
stack_pop(&mut stack, &op, &[Types::Int])?;
},
InstructionType::Dup => {
let a = stack_pop(&mut stack, &op, &[Types::Any])?;
stack.push(a);
},
InstructionType::Rot => {
let a = stack_pop(&mut stack, &op, &[Types::Any])?;
let b = stack_pop(&mut stack, &op, &[Types::Any])?;
let c = stack_pop(&mut stack, &op, &[Types::Any])?;
stack.push(b);
stack.push(a);
stack.push(c);
},
InstructionType::Over => {
let a = stack_pop(&mut stack, &op, &[Types::Any])?;
let b = stack_pop(&mut stack, &op, &[Types::Any])?;
stack.push(b.clone());
stack.push(a);
stack.push(b);
},
InstructionType::Swap => {
let a = stack_pop(&mut stack, &op, &[Types::Any])?;
let b = stack_pop(&mut stack, &op, &[Types::Any])?;
stack.push(a);
stack.push(b);
},
InstructionType::Minus => {
stack_pop(&mut stack, &op, &[Types::Int])?;
stack_pop(&mut stack, &op, &[Types::Int, Types::Ptr])?;
stack.push(Types::Int);
},
InstructionType::Plus => {
stack_pop(&mut stack, &op, &[Types::Int])?;
stack_pop(&mut stack, &op, &[Types::Int, Types::Ptr])?;
stack.push(Types::Int);
},
InstructionType::Equals => {
stack_pop(&mut stack, &op, &[Types::Int, Types::Ptr])?;
stack_pop(&mut stack, &op, &[Types::Int, Types::Ptr])?;
stack.push(Types::Bool);
},
InstructionType::Gt => {
stack_pop(&mut stack, &op, &[Types::Int, Types::Ptr])?;
stack_pop(&mut stack, &op, &[Types::Int, Types::Ptr])?;
stack.push(Types::Bool);
},
InstructionType::Lt => {
stack_pop(&mut stack, &op, &[Types::Int, Types::Ptr])?;
stack_pop(&mut stack, &op, &[Types::Int, Types::Ptr])?;
stack.push(Types::Bool);
},
InstructionType::Ge => {
stack_pop(&mut stack, &op, &[Types::Int, Types::Ptr])?;
stack_pop(&mut stack, &op, &[Types::Int, Types::Ptr])?;
stack.push(Types::Bool);
},
InstructionType::Le => {
stack_pop(&mut stack, &op, &[Types::Int, Types::Ptr])?;
stack_pop(&mut stack, &op, &[Types::Int, Types::Ptr])?;
stack.push(Types::Bool);
},
InstructionType::NotEquals => {
stack_pop(&mut stack, &op, &[Types::Int, Types::Ptr])?;
stack_pop(&mut stack, &op, &[Types::Int, Types::Ptr])?;
stack.push(Types::Bool);
},
InstructionType::Band => {
stack_pop(&mut stack, &op, &[Types::Int])?;
stack_pop(&mut stack, &op, &[Types::Int])?;
stack.push(Types::Int);
},
InstructionType::Bor => {
stack_pop(&mut stack, &op, &[Types::Int])?;
stack_pop(&mut stack, &op, &[Types::Int])?;
stack.push(Types::Int);
},
InstructionType::Shr => {
stack_pop(&mut stack, &op, &[Types::Int])?;
stack_pop(&mut stack, &op, &[Types::Int])?;
stack.push(Types::Int);
},
InstructionType::Shl => {
stack_pop(&mut stack, &op, &[Types::Int])?;
stack_pop(&mut stack, &op, &[Types::Int])?;
stack.push(Types::Int);
},
InstructionType::DivMod => {
stack_pop(&mut stack, &op, &[Types::Int])?;
stack_pop(&mut stack, &op, &[Types::Int])?;
stack.push(Types::Int);
stack.push(Types::Int);
},
InstructionType::Mul => {
stack_pop(&mut stack, &op, &[Types::Int])?;
stack_pop(&mut stack, &op, &[Types::Int])?;
stack.push(Types::Int);
},
InstructionType::Mem => {
stack.push(Types::Ptr);
},
InstructionType::Load8 => {
stack_pop(&mut stack, &op, &[Types::Ptr])?;
stack.push(Types::Int);
},
InstructionType::Store8 => {
stack_pop(&mut stack, &op, &[Types::Int])?;
stack_pop(&mut stack, &op, &[Types::Ptr])?;
},
InstructionType::Syscall0 => {
stack_pop(&mut stack, &op, &[Types::Int])?;
stack.push(Types::Int);
},
InstructionType::Syscall1 => {
stack_pop(&mut stack, &op, &[Types::Int])?;
stack_pop(&mut stack, &op, &[Types::Any])?;
stack.push(Types::Int);
},
InstructionType::Syscall2 => {
stack_pop(&mut stack, &op, &[Types::Int])?;
stack_pop(&mut stack, &op, &[Types::Any])?;
stack_pop(&mut stack, &op, &[Types::Any])?;
stack.push(Types::Int);
},
InstructionType::Syscall3 => {
stack_pop(&mut stack, &op, &[Types::Int])?;
stack_pop(&mut stack, &op, &[Types::Any])?;
stack_pop(&mut stack, &op, &[Types::Any])?;
stack_pop(&mut stack, &op, &[Types::Any])?;
stack.push(Types::Int);
},
InstructionType::Syscall4 => {
stack_pop(&mut stack, &op, &[Types::Int])?;
stack_pop(&mut stack, &op, &[Types::Any])?;
stack_pop(&mut stack, &op, &[Types::Any])?;
stack_pop(&mut stack, &op, &[Types::Any])?;
stack_pop(&mut stack, &op, &[Types::Any])?;
stack.push(Types::Int);
},
InstructionType::Syscall5 => {
stack_pop(&mut stack, &op, &[Types::Int])?;
stack_pop(&mut stack, &op, &[Types::Any])?;
stack_pop(&mut stack, &op, &[Types::Any])?;
stack_pop(&mut stack, &op, &[Types::Any])?;
stack_pop(&mut stack, &op, &[Types::Any])?;
stack_pop(&mut stack, &op, &[Types::Any])?;
stack.push(Types::Int);
},
InstructionType::Syscall6 => {
stack_pop(&mut stack, &op, &[Types::Int])?;
stack_pop(&mut stack, &op, &[Types::Any])?;
stack_pop(&mut stack, &op, &[Types::Any])?;
stack_pop(&mut stack, &op, &[Types::Any])?;
stack_pop(&mut stack, &op, &[Types::Any])?;
stack_pop(&mut stack, &op, &[Types::Any])?;
stack_pop(&mut stack, &op, &[Types::Any])?;
stack.push(Types::Int);
},
InstructionType::CastBool => {
stack_pop(&mut stack, &op, &[Types::Any])?;
stack.push(Types::Bool);
},
InstructionType::CastPtr => {
stack_pop(&mut stack, &op, &[Types::Any])?;
stack.push(Types::Ptr);
},
InstructionType::CastInt => {
stack_pop(&mut stack, &op, &[Types::Any])?;
stack.push(Types::Int);
},
InstructionType::None => {},
}
},
}
}
Ok(ops.to_vec())
}
fn stack_pop(v: &mut Vec<Types>, op: &Operator, t: &[Types]) -> Result<Types> {
if v.is_empty() {
lerror!(&op.loc, "Expected {:?}, but got nothing", t);
return Err(eyre!(""));
}
let r = v.pop().unwrap();
if !t.contains(&r) && t[0] != Types::Any {
lerror!(&op.loc, "Expected {:?}, but got {:?}", t, r);
return Err(eyre!(""));
}
Ok(r)
}

View File

@ -1 +1,3 @@
' ' print include "./asd.mcl"
1 test