diff --git a/examples/hello_world.mcl b/examples/hello_world.mcl index b206a6d..a7fef71 100644 --- a/examples/hello_world.mcl +++ b/examples/hello_world.mcl @@ -1,18 +1,4 @@ +include "std.mcl" -mem dup 72 @8 -1 + dup 101 @8 -1 + dup 110 @8 -1 + dup 108 @8 -1 + dup 111 @8 -1 + dup 32 @8 -1 + dup 119 @8 -1 + dup 111 @8 -1 + dup 114 @8 -1 + dup 108 @8 -1 + dup 100 @8 -1 + dup 33 @8 -1 + dup 10 @8 -1 + - -mem - mem 1 1 syscall3 +"Henlo World! :3\n" puts diff --git a/examples/rule110.mcl b/examples/rule110.mcl index 4cec46f..916e49d 100755 --- a/examples/rule110.mcl +++ b/examples/rule110.mcl @@ -1,4 +1,4 @@ -include "io.mcl" +include "std.mcl" macro BOARD_SIZE 100 end diff --git a/include/fs.mcl b/include/fs.mcl new file mode 100644 index 0000000..2060661 --- /dev/null +++ b/include/fs.mcl @@ -0,0 +1,19 @@ + +macro FS_O_APPEND 1024 end // append to existing file +macro FS_O_ASYNC 8192 end // use signal-driven IO +macro FS_O_CLOEXEC 524288 end // use close-on-exec (avoid race conditions and lock contentions) +macro FS_O_CREAT 64 end // create file if it doesn’t exist +macro FS_O_DIRECT 16384 end // bypass cache (slower) +macro FS_O_DIRECTORY 65536 end // fail if pathname isn’t a directory +macro FS_O_DSYNC 4096 end // ensure output is sent to hardware and metadata written before return +macro FS_O_EXCL 128 end // ensure creation of file +macro FS_O_LARGEFILE 0 end // allows use of file sizes represented by off64_t +macro FS_O_NOATIME 262144 end // do not increment access time upon open +macro FS_O_NOCTTY 256 end // if pathname is a terminal device, don’t become controlling terminal +macro FS_O_NOFOLLOW 131072 end // fail if pathname is symbolic link +macro FS_O_NONBLOCK 2048 end // if possible, open file with non-blocking IO +macro FS_O_NDELAY 2048 end // same as O_NONBLOCK +macro FS_O_PATH 2097152 end // open descriptor for obtaining permissions and status of a file but does not allow read/write operations +macro FS_O_SYNC 1052672 end // wait for IO to complete before returning +macro FS_O_TMPFILE 4259840 end // create an unnamed, unreachable (via any other open call) temporary file +macro FS_O_TRUNC 512 end // if file exists, ovewrite it (careful!) diff --git a/include/int.mcl b/include/int.mcl index 6a5e3b9..c74ee7e 100644 --- a/include/int.mcl +++ b/include/int.mcl @@ -1,5 +1,16 @@ macro NULL 0 end macro false 0 end macro true 1 end + macro div divmod drop end -macro mod divmod swap drop end \ No newline at end of file +macro mod divmod swap drop end +macro / div end +macro % mod end + +macro 2dup over over end +macro 2drop drop drop end + +macro sizeof(u64) 8 end +macro sizeof(u32) 4 end +macro sizeof(u16) 2 end +macro sizeof(u8) 1 end \ No newline at end of file diff --git a/include/io.mcl b/include/io.mcl index b37d846..76b7ae5 100644 --- a/include/io.mcl +++ b/include/io.mcl @@ -1,21 +1,29 @@ -include "linux.mcl" - // Write to a file descriptor using the SYS_write syscall -// args: [str_size, str_ptr, fd] -// @arg str_size: Int -// @arg str_ptr: Ptr -// @arg fd: Int +// args: [buff_size, buff_ptr, fd] +// @arg buff_size: Int - number of bytes to write +// @arg buff_ptr: Ptr - pointer to the buffer to write +// @arg fd: Int - file descriptor // @ret Int macro write SYS_write syscall3 end +// Write to a file descriptor using the SYS_write syscall +// args: [buff_size, buff_ptr, fd] +// @arg buff_size: Int - number of bytes to write +// @arg buff_ptr: Ptr - pointer to the buffer to write +// @arg fd: Int - file descriptor +// @ret Int +macro read + SYS_read syscall3 +end + // Print a string to STDOUT // args: [str_size, str_ptr] -// @arg str_size: Int -// @arg str_ptr: Ptr +// @arg buff_size: Int - number of bytes to write +// @arg buff_ptr: Ptr - pointer to the buffer to write // @ret NULL macro puts STDOUT write drop @@ -23,8 +31,8 @@ end // Print a string to STDERR // args: [str_size, str_ptr] -// @arg str_size: Int -// @arg str_ptr: Ptr +// @arg buff_size: Int - number of bytes to write +// @arg buff_ptr: Ptr - pointer to the buffer to write // @ret NULL macro eputs STDOUT write drop diff --git a/include/mem.mcl b/include/mem.mcl new file mode 100644 index 0000000..2f1ae8e --- /dev/null +++ b/include/mem.mcl @@ -0,0 +1,27 @@ + +macro load8 @8 end +macro store8 !8 end + +macro load64 + 7 + 0 + 8 shl over !8 + swap 1 - swap + 8 shl over !8 + swap 1 - swap + 8 shl over !8 + swap 1 - swap + 8 shl over !8 + swap 1 - swap + 8 shl over !8 + swap 1 - swap + 8 shl over !8 + swap 1 - swap + 8 shl over !8 + swap 1 - swap + 8 shl over !8 + swap drop +end + +macro store64 + 2dup 255 band @8 shr swap 1 + swap + 2dup 255 band @8 shr swap 1 + swap + 2dup 255 band @8 shr swap 1 + swap + 2dup 255 band @8 shr swap 1 + swap + 2dup 255 band @8 shr swap 1 + swap + 2dup 255 band @8 shr swap 1 + swap + 2dup 255 band @8 shr swap 1 + swap + 2dup 255 band @8 shr swap 2drop +end + diff --git a/include/std.mcl b/include/std.mcl new file mode 100644 index 0000000..78fcb01 --- /dev/null +++ b/include/std.mcl @@ -0,0 +1,5 @@ +include "linux.mcl" +include "io.mcl" +include "util.mcl" +include "int.mcl" +include "fs.mcl" \ No newline at end of file diff --git a/src/compile/linux_x86_64.rs b/src/compile/linux_x86_64.rs index 06e1071..5b1a7b9 100644 --- a/src/compile/linux_x86_64.rs +++ b/src/compile/linux_x86_64.rs @@ -1,8 +1,8 @@ use std::{fs, path::PathBuf, io::{Write, BufWriter}}; -use crate::{constants::{Operator, OpType}, Args}; +use crate::{constants::{Operator, OpType, KeywordType}, Args}; use color_eyre::Result; use crate::compile::commands::linux_x86_64_compile_and_link; - +use crate::constants::InstructionType; use super::commands::linux_x86_64_run; @@ -77,13 +77,13 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result{ writeln!(writer, "addr_{ti}:")?; match token.typ { // stack - OpType::PushInt => { + OpType::Instruction(InstructionType::PushInt) => { writeln!(writer, " ;; -- push int {}", token.value)?; writeln!(writer, " mov rax, {}", token.value)?; writeln!(writer, " push rax")?; ti += 1; }, - OpType::PushStr => { + OpType::Instruction(InstructionType::PushStr) => { writeln!(writer, " ;; -- push str \"{}\"", token.text.escape_default())?; writeln!(writer, " mov rax, {}", token.text.len())?; writeln!(writer, " push rax")?; @@ -91,19 +91,19 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result{ strings.push(token.text.clone()); ti += 1; } - OpType::Drop => { + OpType::Instruction(InstructionType::Drop) => { writeln!(writer, " ;; -- drop")?; writeln!(writer, " pop rax")?; ti += 1; }, - OpType::Print => { + OpType::Instruction(InstructionType::Print) => { writeln!(writer, " ;; -- print")?; writeln!(writer, " pop rdi")?; writeln!(writer, " call print")?; ti += 1; }, - OpType::Dup => { + OpType::Instruction(InstructionType::Dup) => { writeln!(writer, " ;; -- dup")?; writeln!(writer, " pop rax")?; writeln!(writer, " push rax")?; @@ -111,19 +111,8 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result{ ti += 1; }, - OpType::Dup2 => { - writeln!(writer, " ;; -- 2dup")?; - writeln!(writer, " pop rbx")?; - writeln!(writer, " pop rax")?; - writeln!(writer, " push rax")?; - writeln!(writer, " push rbx")?; - writeln!(writer, " push rax")?; - writeln!(writer, " push rbx")?; - ti += 1; - }, - - OpType::Rot => { + OpType::Instruction(InstructionType::Rot) => { writeln!(writer, " ;; -- rot")?; writeln!(writer, " pop rax")?; writeln!(writer, " pop rbx")?; @@ -134,7 +123,7 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result{ ti += 1; }, - OpType::Swap => { + OpType::Instruction(InstructionType::Swap) => { writeln!(writer, " ;; -- swap")?; writeln!(writer, " pop rax")?; writeln!(writer, " pop rbx")?; @@ -143,7 +132,7 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result{ ti += 1; }, - OpType::Over => { + OpType::Instruction(InstructionType::Over) => { writeln!(writer, " ;; -- over")?; writeln!(writer, " pop rax")?; writeln!(writer, " pop rbx")?; @@ -155,12 +144,12 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result{ }, //mem - OpType::Mem => { + OpType::Instruction(InstructionType::Mem) => { writeln!(writer, " ;; -- mem")?; writeln!(writer, " push mem")?; ti += 1; } - OpType::Load8 => { + OpType::Instruction(InstructionType::Load8) => { writeln!(writer, " ;; -- load")?; writeln!(writer, " pop rax")?; writeln!(writer, " xor rbx, rbx")?; @@ -169,7 +158,7 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result{ ti += 1; } - OpType::Store8 => { + OpType::Instruction(InstructionType::Store8) => { writeln!(writer, " ;; -- store")?; writeln!(writer, " pop rbx")?; writeln!(writer, " pop rax")?; @@ -178,7 +167,7 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result{ } // math - OpType::Plus => { + OpType::Instruction(InstructionType::Plus) => { writeln!(writer, " ;; -- plus")?; writeln!(writer, " pop rax")?; writeln!(writer, " pop rbx")?; @@ -186,7 +175,7 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result{ writeln!(writer, " push rax")?; ti += 1; }, - OpType::Minus => { + OpType::Instruction(InstructionType::Minus) => { writeln!(writer, " ;; -- minus")?; writeln!(writer, " pop rax")?; writeln!(writer, " pop rbx")?; @@ -194,7 +183,7 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result{ writeln!(writer, " push rbx")?; ti += 1; }, - OpType::Equals => { + OpType::Instruction(InstructionType::Equals) => { writeln!(writer, " ;; -- equals")?; writeln!(writer, " mov rcx, 0")?; writeln!(writer, " mov rdx, 1")?; @@ -205,7 +194,7 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result{ writeln!(writer, " push rcx")?; ti += 1; }, - OpType::Lt => { + OpType::Instruction(InstructionType::Lt) => { writeln!(writer, " ;; -- lt")?; writeln!(writer, " mov rcx, 0")?; writeln!(writer, " mov rdx, 1")?; @@ -216,7 +205,7 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result{ writeln!(writer, " push rcx")?; ti += 1; }, - OpType::Gt => { + OpType::Instruction(InstructionType::Gt) => { writeln!(writer, " ;; -- gt")?; writeln!(writer, " mov rcx, 0")?; writeln!(writer, " mov rdx, 1")?; @@ -227,7 +216,7 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result{ writeln!(writer, " push rcx")?; ti += 1; }, - OpType::NotEquals => { + OpType::Instruction(InstructionType::NotEquals) => { writeln!(writer, " ;; -- not equals")?; writeln!(writer, " mov rcx, 1")?; writeln!(writer, " mov rdx, 0")?; @@ -238,7 +227,7 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result{ writeln!(writer, " push rcx")?; ti += 1; }, - OpType::Le => { + OpType::Instruction(InstructionType::Le) => { writeln!(writer, " ;; -- lt")?; writeln!(writer, " mov rcx, 0")?; writeln!(writer, " mov rdx, 1")?; @@ -249,7 +238,7 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result{ writeln!(writer, " push rcx")?; ti += 1; }, - OpType::Ge => { + OpType::Instruction(InstructionType::Ge) => { writeln!(writer, " ;; -- gt")?; writeln!(writer, " mov rcx, 0")?; writeln!(writer, " mov rdx, 1")?; @@ -260,7 +249,7 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result{ writeln!(writer, " push rcx")?; ti += 1; }, - OpType::Band => { + OpType::Instruction(InstructionType::Band) => { writeln!(writer, " ;; -- band")?; writeln!(writer, " pop rax")?; writeln!(writer, " pop rbx")?; @@ -268,7 +257,7 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result{ writeln!(writer, " push rbx")?; ti += 1; }, - OpType::Bor => { + OpType::Instruction(InstructionType::Bor) => { writeln!(writer, " ;; -- bor")?; writeln!(writer, " pop rax")?; writeln!(writer, " pop rbx")?; @@ -276,7 +265,7 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result{ writeln!(writer, " push rbx")?; ti += 1; }, - OpType::Shr => { + OpType::Instruction(InstructionType::Shr) => { writeln!(writer, " ;; -- shr")?; writeln!(writer, " pop rcx")?; writeln!(writer, " pop rbx")?; @@ -284,7 +273,7 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result{ writeln!(writer, " push rbx")?; ti += 1; }, - OpType::Shl => { + OpType::Instruction(InstructionType::Shl) => { writeln!(writer, " ;; -- shl")?; writeln!(writer, " pop rcx")?; writeln!(writer, " pop rbx")?; @@ -292,7 +281,7 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result{ writeln!(writer, " push rbx")?; ti += 1; }, - OpType::DivMod => { + OpType::Instruction(InstructionType::DivMod) => { writeln!(writer, " ;; -- div")?; writeln!(writer, " xor rdx, rdx")?; writeln!(writer, " pop rbx")?; @@ -302,7 +291,7 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result{ writeln!(writer, " push rdx")?; ti += 1; }, - OpType::Mul => { + OpType::Instruction(InstructionType::Mul) => { writeln!(writer, " ;; -- mul")?; writeln!(writer, " pop rax")?; writeln!(writer, " pop rbx")?; @@ -313,44 +302,44 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result{ // block - OpType::If => { + 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::Else => { + OpType::Keyword(KeywordType::Else) => { writeln!(writer, " ;; -- else")?; writeln!(writer, " jmp addr_{}", token.jmp)?; ti += 1; }, - OpType::While => { + OpType::Keyword(KeywordType::While) => { writeln!(writer, " ;; -- while")?; ti += 1; } - OpType::Do => { + 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::End => { + OpType::Keyword(KeywordType::End) => { writeln!(writer, " ;; -- end")?; if ti + 1 != token.jmp { writeln!(writer, " jmp addr_{}", token.jmp)?; } ti += 1; }, - OpType::Syscall0 => { + OpType::Instruction(InstructionType::Syscall0) => { writeln!(writer, " ;; -- syscall0")?; writeln!(writer, " pop rax")?; writeln!(writer, " syscall")?; writeln!(writer, " push rax")?; ti += 1; }, - OpType::Syscall1 => { + OpType::Instruction(InstructionType::Syscall1) => { writeln!(writer, " ;; -- syscall1")?; writeln!(writer, " pop rax")?; writeln!(writer, " pop rdi")?; @@ -358,7 +347,7 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result{ writeln!(writer, " push rax")?; ti += 1; }, - OpType::Syscall2 => { + OpType::Instruction(InstructionType::Syscall2) => { writeln!(writer, " ;; -- syscall2")?; writeln!(writer, " pop rax")?; writeln!(writer, " pop rdi")?; @@ -367,7 +356,7 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result{ writeln!(writer, " push rax")?; ti += 1; }, - OpType::Syscall3 => { + OpType::Instruction(InstructionType::Syscall3) => { writeln!(writer, " ;; -- syscall3")?; writeln!(writer, " pop rax")?; writeln!(writer, " pop rdi")?; @@ -378,7 +367,7 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result{ ti += 1; }, - OpType::Syscall4 => { + OpType::Instruction(InstructionType::Syscall4) => { writeln!(writer, " ;; -- syscall4")?; writeln!(writer, " pop rax")?; writeln!(writer, " pop rdi")?; @@ -389,7 +378,7 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result{ writeln!(writer, " push rax")?; ti += 1; }, - OpType::Syscall5 => { + OpType::Instruction(InstructionType::Syscall5) => { writeln!(writer, " ;; -- syscall5")?; writeln!(writer, " pop rax")?; writeln!(writer, " pop rdi")?; @@ -401,7 +390,7 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result{ writeln!(writer, " push rax")?; ti += 1; }, - OpType::Syscall6 => { + OpType::Instruction(InstructionType::Syscall6) => { writeln!(writer, " ;; -- syscall6")?; writeln!(writer, " pop rax")?; writeln!(writer, " pop rdi")?; @@ -414,7 +403,7 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result{ writeln!(writer, " push rax")?; ti += 1; }, - OpType::None | OpType::Macro | OpType::Include => unreachable!() + OpType::Instruction(InstructionType::None) | OpType::Keyword(KeywordType::Macro) | OpType::Keyword(KeywordType::Include) => unreachable!() } } writeln!(writer, "addr_{ti}:")?; diff --git a/src/constants.rs b/src/constants.rs index e56f5a1..aa203bf 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -3,7 +3,7 @@ pub const ALLOW_MACRO_REDEFINITION: bool = true; #[derive(Debug, Clone, PartialEq)] -pub enum OpType { +pub enum InstructionType { // stack PushInt, @@ -11,7 +11,6 @@ pub enum OpType { Drop, Print, Dup, - Dup2, // a b => a b a b Rot, // a b c => b c a Over, // a b => a b a Swap, // a b => b a @@ -37,15 +36,6 @@ pub enum OpType { Mem, Load8, Store8, - - // block - If, - Else, - End, - While, - Do, - Macro, - Include, // syscalls Syscall0, @@ -59,9 +49,25 @@ pub enum OpType { None // Used for macros and any other non built in word definitions } +#[derive(Debug, Clone, PartialEq)] +pub enum KeywordType { + If, + Else, + End, + While, + Do, + Macro, + Include, +} + +#[derive(Debug, Clone, PartialEq)] +pub enum OpType { + Keyword(KeywordType), + Instruction(InstructionType) +} #[derive(Debug, Clone)] -pub struct Operator { +pub struct Operator{ pub typ: OpType, pub value: usize, pub text: String, //? only used for OpType::PushStr @@ -87,47 +93,46 @@ impl Operator { impl OpType { pub fn human(&self) -> String { match *self { - OpType::PushInt => "Number", - OpType::PushStr => "String", - OpType::Print => "print", - OpType::Dup => "dup", - OpType::Drop => "drop", - OpType::Dup2 => "2dup", - OpType::Rot => "rot", - OpType::Over => "over", - OpType::Swap => "swap", - OpType::Plus => "+", - OpType::Minus => "-", - OpType::Equals => "=", - OpType::Gt => ">", - OpType::Lt => "<", - OpType::NotEquals => "!=", - OpType::Le => "<=", - OpType::Ge => ">=", - OpType::Band => "band", - OpType::Bor => "bor", - OpType::Shr => "shr", - OpType::Shl => "shl", - OpType::DivMod => "divmod", - OpType::Mul => "*", - OpType::If => "if", - OpType::Else => "else", - OpType::End => "end", - OpType::While => "while", - OpType::Do => "do", - OpType::Macro => "macro", - OpType::Include => "include", - OpType::Mem => "mem", - OpType::Load8 => "!8", - OpType::Store8 => "@8", - OpType::Syscall0 => "syscall0", - OpType::Syscall1 => "syscall1", - OpType::Syscall2 => "syscall2", - OpType::Syscall3 => "syscall3", - OpType::Syscall4 => "syscall4", - OpType::Syscall5 => "syscall5", - OpType::Syscall6 => "syscall6", - OpType::None => "None" + OpType::Instruction(InstructionType::PushInt) => "Number", + OpType::Instruction(InstructionType::PushStr) => "String", + OpType::Instruction(InstructionType::Print) => "print", + OpType::Instruction(InstructionType::Dup) => "dup", + OpType::Instruction(InstructionType::Drop) => "drop", + OpType::Instruction(InstructionType::Rot) => "rot", + OpType::Instruction(InstructionType::Over) => "over", + OpType::Instruction(InstructionType::Swap) => "swap", + OpType::Instruction(InstructionType::Plus) => "+", + OpType::Instruction(InstructionType::Minus) => "-", + OpType::Instruction(InstructionType::Equals) => "=", + OpType::Instruction(InstructionType::Gt) => ">", + OpType::Instruction(InstructionType::Lt) => "<", + OpType::Instruction(InstructionType::NotEquals) => "!=", + OpType::Instruction(InstructionType::Le) => "<=", + OpType::Instruction(InstructionType::Ge) => ">=", + OpType::Instruction(InstructionType::Band) => "band", + OpType::Instruction(InstructionType::Bor) => "bor", + OpType::Instruction(InstructionType::Shr) => "shr", + OpType::Instruction(InstructionType::Shl) => "shl", + OpType::Instruction(InstructionType::DivMod) => "divmod", + OpType::Instruction(InstructionType::Mul) => "*", + OpType::Keyword(KeywordType::If) => "if", + OpType::Keyword(KeywordType::Else) => "else", + OpType::Keyword(KeywordType::End) => "end", + OpType::Keyword(KeywordType::While) => "while", + OpType::Keyword(KeywordType::Do) => "do", + OpType::Keyword(KeywordType::Macro) => "macro", + OpType::Keyword(KeywordType::Include) => "include", + OpType::Instruction(InstructionType::Mem) => "mem", + OpType::Instruction(InstructionType::Load8) => "!8", + OpType::Instruction(InstructionType::Store8) => "@8", + OpType::Instruction(InstructionType::Syscall0) => "syscall0", + OpType::Instruction(InstructionType::Syscall1) => "syscall1", + OpType::Instruction(InstructionType::Syscall2) => "syscall2", + OpType::Instruction(InstructionType::Syscall3) => "syscall3", + OpType::Instruction(InstructionType::Syscall4) => "syscall4", + OpType::Instruction(InstructionType::Syscall5) => "syscall5", + OpType::Instruction(InstructionType::Syscall6) => "syscall6", + OpType::Instruction(InstructionType::None) => "None" }.to_string() } } diff --git a/src/interpret/linux_x86_64/mod.rs b/src/interpret/linux_x86_64/mod.rs index ec1ea78..a53f34d 100644 --- a/src/interpret/linux_x86_64/mod.rs +++ b/src/interpret/linux_x86_64/mod.rs @@ -1,4 +1,4 @@ -use crate::{constants::{OpType, Loc}, lerror, error}; +use crate::{constants::{OpType, Loc, InstructionType, KeywordType}, lerror, error}; // use crate::util::logger; use color_eyre::Result; use eyre::eyre; @@ -27,11 +27,11 @@ pub fn run(tokens: &[crate::constants::Operator]) -> Result{ match token.typ { // stack - OpType::PushInt => { + OpType::Instruction(InstructionType::PushInt) => { stack.push(token.value); ti += 1; }, - OpType::PushStr => { + OpType::Instruction(InstructionType::PushStr) => { if token.addr.is_none() { stack.push(token.text.len()); // string len stack.push(string_idx + crate::compile::MEM_SZ); @@ -50,26 +50,18 @@ pub fn run(tokens: &[crate::constants::Operator]) -> Result{ ti += 1; }, - OpType::Drop => { + OpType::Instruction(InstructionType::Drop) => { stack.pop(); ti += 1; }, - OpType::Dup => { + OpType::Instruction(InstructionType::Dup) => { let a = stack_pop(&mut stack, &pos)?; stack.push(a); stack.push(a); ti += 1; }, - OpType::Dup2 => { - let a = stack_pop(&mut stack, &pos)?; - let b = stack_pop(&mut stack, &pos)?; - stack.push(b); - stack.push(a); - stack.push(b); - stack.push(a); - ti += 1; - } - OpType::Rot => { + + OpType::Instruction(InstructionType::Rot) => { let a = stack_pop(&mut stack, &pos)?; let b = stack_pop(&mut stack, &pos)?; let c = stack_pop(&mut stack, &pos)?; @@ -78,14 +70,14 @@ pub fn run(tokens: &[crate::constants::Operator]) -> Result{ stack.push(c); ti += 1; } - OpType::Swap => { + OpType::Instruction(InstructionType::Swap) => { let a = stack_pop(&mut stack, &pos)?; let b = stack_pop(&mut stack, &pos)?; stack.push(a); stack.push(b); ti += 1; } - OpType::Over => { + OpType::Instruction(InstructionType::Over) => { let a = stack_pop(&mut stack, &pos)?; let b = stack_pop(&mut stack, &pos)?; stack.push(b); @@ -94,7 +86,7 @@ pub fn run(tokens: &[crate::constants::Operator]) -> Result{ ti += 1; } - OpType::Print => { + OpType::Instruction(InstructionType::Print) => { let a = stack_pop(&mut stack, &pos)?; println!("{a}"); // let _ = io::stdout().flush(); @@ -102,18 +94,18 @@ pub fn run(tokens: &[crate::constants::Operator]) -> Result{ }, // mem - OpType::Mem => { + OpType::Instruction(InstructionType::Mem) => { stack.push(0); ti += 1; } - OpType::Load8 => { + OpType::Instruction(InstructionType::Load8) => { let a = stack_pop(&mut stack, &pos)?; let byte = mem[a]; stack.push(byte as usize); ti += 1; } #[allow(clippy::cast_possible_truncation)] - OpType::Store8 => { + OpType::Instruction(InstructionType::Store8) => { let val = stack_pop(&mut stack, &pos)?; let addr = stack_pop(&mut stack, &pos)?; @@ -122,91 +114,91 @@ pub fn run(tokens: &[crate::constants::Operator]) -> Result{ } // math - OpType::Plus => { + OpType::Instruction(InstructionType::Plus) => { let a = stack_pop(&mut stack, &pos)?; let b = stack_pop(&mut stack, &pos)?; stack.push(b + a); ti += 1; }, - OpType::Minus => { + OpType::Instruction(InstructionType::Minus) => { let a = stack_pop(&mut stack, &pos)?; let b = stack_pop(&mut stack, &pos)?; stack.push(b - a); ti += 1; }, - OpType::Equals => { + OpType::Instruction(InstructionType::Equals) => { let a = stack_pop(&mut stack, &pos)?; let b = stack_pop(&mut stack, &pos)?; stack.push(usize::from(b == a)); ti += 1; }, - OpType::Gt => { + OpType::Instruction(InstructionType::Gt) => { let a = stack_pop(&mut stack, &pos)?; let b = stack_pop(&mut stack, &pos)?; stack.push(usize::from(b > a)); ti += 1; }, - OpType::Lt => { + OpType::Instruction(InstructionType::Lt) => { let a = stack_pop(&mut stack, &pos)?; let b = stack_pop(&mut stack, &pos)?; stack.push(usize::from(b < a)); ti += 1; }, - OpType::NotEquals => { + OpType::Instruction(InstructionType::NotEquals) => { let a = stack_pop(&mut stack, &pos)?; let b = stack_pop(&mut stack, &pos)?; stack.push(usize::from(b != a)); ti += 1; }, - OpType::Ge => { + OpType::Instruction(InstructionType::Ge) => { let a = stack_pop(&mut stack, &pos)?; let b = stack_pop(&mut stack, &pos)?; stack.push(usize::from(b >= a)); ti += 1; }, - OpType::Le => { + OpType::Instruction(InstructionType::Le) => { let a = stack_pop(&mut stack, &pos)?; let b = stack_pop(&mut stack, &pos)?; stack.push(usize::from(b <= a)); ti += 1; }, - OpType::Band => { + OpType::Instruction(InstructionType::Band) => { let a = stack_pop(&mut stack, &pos)?; let b = stack_pop(&mut stack, &pos)?; stack.push(a & b); ti += 1; } - OpType::Bor => { + OpType::Instruction(InstructionType::Bor) => { let a = stack_pop(&mut stack, &pos)?; let b = stack_pop(&mut stack, &pos)?; stack.push(a | b); ti += 1; } - OpType::Shr => { + OpType::Instruction(InstructionType::Shr) => { let a = stack_pop(&mut stack, &pos)?; let b = stack_pop(&mut stack, &pos)?; stack.push(b >> a); ti += 1; } - OpType::Shl => { + OpType::Instruction(InstructionType::Shl) => { let a = stack_pop(&mut stack, &pos)?; let b = stack_pop(&mut stack, &pos)?; stack.push(b << a); ti += 1; } - OpType::DivMod => { + OpType::Instruction(InstructionType::DivMod) => { let a = stack_pop(&mut stack, &pos)?; let b = stack_pop(&mut stack, &pos)?; stack.push(b / a); stack.push(b % a); ti += 1; } - OpType::Mul => { + OpType::Instruction(InstructionType::Mul) => { let a = stack_pop(&mut stack, &pos)?; let b = stack_pop(&mut stack, &pos)?; stack.push(b * a); @@ -215,7 +207,7 @@ pub fn run(tokens: &[crate::constants::Operator]) -> Result{ // blocks - OpType::If => { + OpType::Keyword(KeywordType::If) => { let a = stack_pop(&mut stack, &pos)?; if a == 0 { // println!("If({ti}) => t: {:?} j: {}", tokens[token.jmp as usize].typ, token.jmp); @@ -224,13 +216,13 @@ pub fn run(tokens: &[crate::constants::Operator]) -> Result{ ti += 1; } }, - OpType::Else | OpType::End => { + OpType::Keyword(KeywordType::Else) | OpType::Keyword(KeywordType::End) => { ti = token.jmp; } - OpType::While => { + OpType::Keyword(KeywordType::While) => { ti += 1; } - OpType::Do => { + OpType::Keyword(KeywordType::Do) => { let a = stack.pop().unwrap(); if a == 0 { ti = token.jmp; @@ -238,19 +230,19 @@ pub fn run(tokens: &[crate::constants::Operator]) -> Result{ ti += 1; } } - OpType::Syscall0 => { + OpType::Instruction(InstructionType::Syscall0) => { todo!(); // ti += 1; }, - OpType::Syscall1 => { + OpType::Instruction(InstructionType::Syscall1) => { todo!(); // ti += 1; }, - OpType::Syscall2 => { + OpType::Instruction(InstructionType::Syscall2) => { todo!(); // ti += 1; }, - OpType::Syscall3 => { + 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)?; @@ -268,19 +260,19 @@ pub fn run(tokens: &[crate::constants::Operator]) -> Result{ // println!("{}", stack.len()); ti += 1; }, - OpType::Syscall4 => { + OpType::Instruction(InstructionType::Syscall4) => { todo!(); // ti += 1; }, - OpType::Syscall5 => { + OpType::Instruction(InstructionType::Syscall5) => { todo!(); // ti += 1; }, - OpType::Syscall6 => { + OpType::Instruction(InstructionType::Syscall6) => { todo!(); // ti += 1; }, - OpType::None | OpType::Macro | OpType::Include => unreachable!() + OpType::Instruction(InstructionType::None) | OpType::Keyword(KeywordType::Macro) | OpType::Keyword(KeywordType::Include) => unreachable!() } } diff --git a/src/parser.rs b/src/parser.rs index c559fe3..9c8f444 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -1,6 +1,6 @@ use std::ops::Deref; -use crate::{constants::{Operator, OpType, Token, TokenType, Loc}, lerror}; +use crate::{constants::{Operator, OpType, Token, TokenType, Loc, KeywordType, InstructionType}, lerror}; use color_eyre::Result; use eyre::eyre; @@ -9,12 +9,13 @@ pub fn cross_ref(mut program: Vec) -> Result> { for ip in 0..program.len() { let op = &program.clone()[ip]; match op.typ { - OpType::If | OpType::While => { + OpType::Keyword(KeywordType::If) | + OpType::Keyword(KeywordType::While) => { stack.push(ip); } - OpType::Else => { + OpType::Keyword(KeywordType::Else) => { let if_ip = stack.pop().unwrap(); - if program[if_ip].typ != OpType::If { + if program[if_ip].typ != OpType::Keyword(KeywordType::If) { lerror!(&op.clone().loc,"'end' can only close 'if' blocks"); return Err(eyre!("Bad block")); } @@ -22,16 +23,16 @@ pub fn cross_ref(mut program: Vec) -> Result> { program[if_ip].jmp = ip + 1; stack.push(ip); }, - OpType::End => { + OpType::Keyword(KeywordType::End) => { let block_ip = stack.pop().unwrap(); - if program[block_ip].typ == OpType::If || - program[block_ip].typ == OpType::Else { + if program[block_ip].typ == OpType::Keyword(KeywordType::If) || + program[block_ip].typ == OpType::Keyword(KeywordType::Else) { program[block_ip].jmp = ip; program[ip].jmp = ip + 1; - } else if program[block_ip].typ == OpType::Do { + } else if program[block_ip].typ == OpType::Keyword(KeywordType::Do) { program[ip].jmp = program[block_ip].jmp; program[block_ip].jmp = ip + 1; } else { @@ -40,7 +41,7 @@ pub fn cross_ref(mut program: Vec) -> Result> { } } - OpType::Do => { + OpType::Keyword(KeywordType::Do) => { let while_ip = stack.pop().unwrap(); program[ip].jmp = while_ip; stack.push(ip); @@ -82,10 +83,10 @@ impl Parser { tokens.push(Operator::new(word_type, 0, token.text.clone(), token.file.clone(), token.line, token.col)); }, TokenType::Int => {// negative numbers not yet implemented - tokens.push(Operator::new(OpType::PushInt, token.text.parse::()?, String::new(), token.file.clone(), token.line, token.col)); + tokens.push(Operator::new(OpType::Instruction(InstructionType::PushInt), token.text.parse::()?, String::new(), token.file.clone(), token.line, token.col)); }, TokenType::String => { - tokens.push(Operator::new(OpType::PushStr, 0, token.text.clone(), token.file.clone(), token.line, token.col)); + tokens.push(Operator::new(OpType::Instruction(InstructionType::PushStr), 0, token.text.clone(), token.file.clone(), token.line, token.col)); } TokenType::Char => { let c = token.text.clone(); @@ -94,7 +95,7 @@ impl Parser { return Err(eyre!("")); } - tokens.push(Operator::new(OpType::PushInt, token.text.chars().next().unwrap() as usize, String::new(), token.file.clone(), token.line, token.col)); + tokens.push(Operator::new(OpType::Instruction(InstructionType::PushInt), token.text.chars().next().unwrap() as usize, String::new(), token.file.clone(), token.line, token.col)); } }; @@ -110,53 +111,52 @@ impl Parser { pub fn lookup_word>(s: &str, _pos: P) -> OpType { match s { //stack - "print" => OpType::Print, - "dup" => OpType::Dup, - "drop" => OpType::Drop, - "2dup" => OpType::Dup2, - "rot" => OpType::Rot, - "over" => OpType::Over, - "swap" => OpType::Swap, + "print" => OpType::Instruction(InstructionType::Print), + "dup" => OpType::Instruction(InstructionType::Dup), + "drop" => OpType::Instruction(InstructionType::Drop), + "rot" => OpType::Instruction(InstructionType::Rot), + "over" => OpType::Instruction(InstructionType::Over), + "swap" => OpType::Instruction(InstructionType::Swap), // comp and math - "+" => OpType::Plus, - "-" => OpType::Minus, - "=" => OpType::Equals, - "!=" => OpType::NotEquals, - ">" => OpType::Gt, - "<" => OpType::Lt, - ">=" => OpType::Ge, - "<=" => OpType::Le, + "+" => OpType::Instruction(InstructionType::Plus), + "-" => OpType::Instruction(InstructionType::Minus), + "=" => OpType::Instruction(InstructionType::Equals), + "!=" => OpType::Instruction(InstructionType::NotEquals), + ">" => OpType::Instruction(InstructionType::Gt), + "<" => OpType::Instruction(InstructionType::Lt), + ">=" => OpType::Instruction(InstructionType::Ge), + "<=" => OpType::Instruction(InstructionType::Le), - "band" => OpType::Band, - "bor" => OpType::Bor, - "shr" => OpType::Shr, - "shl" => OpType::Shl, - "divmod" => OpType::DivMod, - "*" => OpType::Mul, + "band" => OpType::Instruction(InstructionType::Band), + "bor" => OpType::Instruction(InstructionType::Bor), + "shr" => OpType::Instruction(InstructionType::Shr), + "shl" => OpType::Instruction(InstructionType::Shl), + "divmod" => OpType::Instruction(InstructionType::DivMod), + "*" => OpType::Instruction(InstructionType::Mul), // block - "if" => OpType::If, - "else" => OpType::Else, - "end" => OpType::End, - "while" => OpType::While, - "do" => OpType::Do, - "macro" => OpType::Macro, - "include" => OpType::Include, + "if" => OpType::Keyword(KeywordType::If), + "else" => OpType::Keyword(KeywordType::Else), + "end" => OpType::Keyword(KeywordType::End), + "while" => OpType::Keyword(KeywordType::While), + "do" => OpType::Keyword(KeywordType::Do), + "macro" => OpType::Keyword(KeywordType::Macro), + "include" => OpType::Keyword(KeywordType::Include), // mem - "mem" => OpType::Mem, - "!8" => OpType::Load8, - "@8" => OpType::Store8, + "mem" => OpType::Instruction(InstructionType::Mem), + "!8" => OpType::Instruction(InstructionType::Load8), + "@8" => OpType::Instruction(InstructionType::Store8), - "syscall0" => OpType::Syscall0, - "syscall1" => OpType::Syscall1, - "syscall2" => OpType::Syscall2, - "syscall3" => OpType::Syscall3, - "syscall4" => OpType::Syscall4, - "syscall5" => OpType::Syscall5, - "syscall6" => OpType::Syscall6, - _ => OpType::None + "syscall0" => OpType::Instruction(InstructionType::Syscall0), + "syscall1" => OpType::Instruction(InstructionType::Syscall1), + "syscall2" => OpType::Instruction(InstructionType::Syscall2), + "syscall3" => OpType::Instruction(InstructionType::Syscall3), + "syscall4" => OpType::Instruction(InstructionType::Syscall4), + "syscall5" => OpType::Instruction(InstructionType::Syscall5), + "syscall6" => OpType::Instruction(InstructionType::Syscall6), + _ => OpType::Instruction(InstructionType::None) } } \ No newline at end of file diff --git a/src/preprocessor.rs b/src/preprocessor.rs index 11a586d..d539ee0 100644 --- a/src/preprocessor.rs +++ b/src/preprocessor.rs @@ -4,7 +4,7 @@ use std::path::PathBuf; use color_eyre::Result; use eyre::eyre; -use crate::constants::{Token, Loc, OpType, TokenType}; +use crate::constants::{Token, Loc, OpType, TokenType, KeywordType, InstructionType}; use crate::lexer::lex; use crate::{lerror, lnote, Args, warn}; use crate::parser::lookup_word; @@ -26,7 +26,7 @@ pub fn preprocess(tokens: Vec, args: &Args) -> Result>{ let op_type = lookup_word(&token.text, &token.loc()); match token.clone() { - _ if op_type == OpType::Macro => { + _ if op_type == OpType::Keyword(KeywordType::Macro) => { if rtokens.is_empty(){ lerror!(&token.loc(), "Macro name not found, expected {} but found nothing", TokenType::Word.human()); return Err(eyre!("")); @@ -38,7 +38,7 @@ pub fn preprocess(tokens: Vec, args: &Args) -> Result>{ return Err(eyre!("")); } let word = lookup_word(¯o_name.text, ¯o_name.loc()); - if word != OpType::None { + if word != OpType::Instruction(InstructionType::None) { lerror!(¯o_name.loc(), "Macro name cannot be a built in word, got '{}'", word.human()); return Err(eyre!("")); } @@ -55,12 +55,12 @@ pub fn preprocess(tokens: Vec, args: &Args) -> Result>{ while !rtokens.is_empty() { let t = rtokens.pop().unwrap(); let typ = lookup_word(&t.text, &t.loc()); - if typ == OpType::End && depth == 0 { + if typ == OpType::Keyword(KeywordType::End) && depth == 0 { break; - } else if typ == OpType::End && depth != 0 { + } else if typ == OpType::Keyword(KeywordType::End) && depth != 0 { depth -= 1; macr.tokens.push(t); - } else if typ == OpType::If || typ == OpType::Do { + } else if typ == OpType::Keyword(KeywordType::If) || typ == OpType::Keyword(KeywordType::Do) { macr.tokens.push(t); depth += 1; } else { @@ -75,7 +75,7 @@ pub fn preprocess(tokens: Vec, args: &Args) -> Result>{ } - _ if op_type == OpType::Include => { + _ if op_type == OpType::Keyword(KeywordType::Include) => { if rtokens.is_empty() { lerror!(&token.loc(), "Include path not found, expected {} but found nothing", TokenType::String.human()); return Err(eyre!("")); @@ -127,10 +127,10 @@ pub fn preprocess(tokens: Vec, args: &Args) -> Result>{ if f.typ == TokenType::Word { lookup_word(&f.text, &f.loc()) } else { - OpType::PushInt // i hate myself, this is a randomly picked optype so its happy and works + OpType::Instruction(InstructionType::PushInt) // i hate myself, this is a randomly picked optype so its happy and works } - }).collect::>().contains(&OpType::None){ + }).collect::>().contains(&OpType::Instruction(InstructionType::None)){ if times >= 50 { warn!("File import depth maxed out, if the program crashes try reducing the import depth, good luck youll need it"); @@ -155,7 +155,7 @@ pub fn expand_macros(tokens: Vec, macros: &HashMap) -> Res let op_type = lookup_word(&op.text, &op.loc()); if op.typ == TokenType::Word { match op_type { - OpType::None => { + OpType::Instruction(InstructionType::None) => { let m = macros.get(&op.text); if m.is_some() { if let Some(m) = m {