From d536bfcf31b8071ccf85833d51fe87c907c32a8f Mon Sep 17 00:00:00 2001 From: MCorange Date: Mon, 20 Mar 2023 16:13:34 +0200 Subject: [PATCH] started implementing stdlib --- include/io.mcl | 42 ++++ include/linux.mcl | 322 ++++++++++++++++++++++++++++++ include/util.mcl | 15 ++ src/compile/linux_x86_64.rs | 7 +- src/constants.rs | 4 +- src/interpret/linux_x86_64/mod.rs | 6 +- src/lexer.rs | 3 + src/main.rs | 26 +-- src/parser.rs | 14 +- src/preprocessor.rs | 39 +++- test.mcl | 5 +- 11 files changed, 445 insertions(+), 38 deletions(-) create mode 100644 include/io.mcl create mode 100644 include/linux.mcl create mode 100644 include/util.mcl diff --git a/include/io.mcl b/include/io.mcl new file mode 100644 index 0000000..b37d846 --- /dev/null +++ b/include/io.mcl @@ -0,0 +1,42 @@ +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 +// @ret Int +macro write + SYS_write syscall3 +end + + +// Print a string to STDOUT +// args: [str_size, str_ptr] +// @arg str_size: Int +// @arg str_ptr: Ptr +// @ret NULL +macro puts + STDOUT write drop +end + +// Print a string to STDERR +// args: [str_size, str_ptr] +// @arg str_size: Int +// @arg str_ptr: Ptr +// @ret NULL +macro eputs + STDOUT write drop +end + +// TODO: make putc and eputc after we make local mem + +// Exit the program with exit_code +// args: [exit_code] +// @arg exit_code: Int +// @ret NULL/NEVER +macro exit + SYS_exit syscall1 drop +end + diff --git a/include/linux.mcl b/include/linux.mcl new file mode 100644 index 0000000..5292b65 --- /dev/null +++ b/include/linux.mcl @@ -0,0 +1,322 @@ + +// file descriptors +macro STDIN 0 end +macro STDOUT 1 end +macro STDERR 2 end + + +// syscalls +macro SYS_read 0 end +macro SYS_write 1 end +macro SYS_open 2 end +macro SYS_close 3 end +macro SYS_stat 4 end +macro SYS_fstat 5 end +macro SYS_lstat 6 end +macro SYS_poll 7 end +macro SYS_lseek 8 end +macro SYS_mmap 9 end +macro SYS_mprotect 10 end +macro SYS_munmap 11 end +macro SYS_brk 12 end +macro SYS_rt_sigaction 13 end +macro SYS_rt_sigprocmask 14 end +macro SYS_rt_sigreturn 15 end +macro SYS_ioctl 16 end +macro SYS_pread64 17 end +macro SYS_pwrite64 18 end +macro SYS_readv 19 end +macro SYS_writev 20 end +macro SYS_access 21 end +macro SYS_pipe 22 end +macro SYS_select 23 end +macro SYS_sched_yield 24 end +macro SYS_mremap 25 end +macro SYS_msync 26 end +macro SYS_mincore 27 end +macro SYS_madvise 28 end +macro SYS_shmget 29 end +macro SYS_shmat 30 end +macro SYS_shmctl 31 end +macro SYS_dup 32 end +macro SYS_dup2 33 end +macro SYS_pause 34 end +macro SYS_nanosleep 35 end +macro SYS_getitimer 36 end +macro SYS_alarm 37 end +macro SYS_setitimer 38 end +macro SYS_getpid 39 end +macro SYS_sendfile 40 end +macro SYS_socket 41 end +macro SYS_connect 42 end +macro SYS_accept 43 end +macro SYS_sendto 44 end +macro SYS_recvfrom 45 end +macro SYS_sendmsg 46 end +macro SYS_recvmsg 47 end +macro SYS_shutdown 48 end +macro SYS_bind 49 end +macro SYS_listen 50 end +macro SYS_getsockname 51 end +macro SYS_getpeername 52 end +macro SYS_socketpair 53 end +macro SYS_setsockopt 54 end +macro SYS_getsockopt 55 end +macro SYS_clone 56 end +macro SYS_fork 57 end +macro SYS_vfork 58 end +macro SYS_execve 59 end +macro SYS_exit 60 end +macro SYS_wait4 61 end +macro SYS_kill 62 end +macro SYS_uname 63 end +macro SYS_semget 64 end +macro SYS_semop 65 end +macro SYS_semctl 66 end +macro SYS_shmdt 67 end +macro SYS_msgget 68 end +macro SYS_msgsnd 69 end +macro SYS_msgrcv 70 end +macro SYS_msgctl 71 end +macro SYS_fcntl 72 end +macro SYS_flock 73 end +macro SYS_fsync 74 end +macro SYS_fdatasync 75 end +macro SYS_truncate 76 end +macro SYS_ftruncate 77 end +macro SYS_getdents 78 end +macro SYS_getcwd 79 end +macro SYS_chdir 80 end +macro SYS_fchdir 81 end +macro SYS_rename 82 end +macro SYS_mkdir 83 end +macro SYS_rmdir 84 end +macro SYS_creat 85 end +macro SYS_link 86 end +macro SYS_unlink 87 end +macro SYS_symlink 88 end +macro SYS_readlink 89 end +macro SYS_chmod 90 end +macro SYS_fchmod 91 end +macro SYS_chown 92 end +macro SYS_fchown 93 end +macro SYS_lchown 94 end +macro SYS_umask 95 end +macro SYS_gettimeofday 96 end +macro SYS_getrlimit 97 end +macro SYS_getrusage 98 end +macro SYS_sysinfo 99 end +macro SYS_times 100 end +macro SYS_ptrace 101 end +macro SYS_getuid 102 end +macro SYS_syslog 103 end +macro SYS_getgid 104 end +macro SYS_setuid 105 end +macro SYS_setgid 106 end +macro SYS_geteuid 107 end +macro SYS_getegid 108 end +macro SYS_setpgid 109 end +macro SYS_getppid 110 end +macro SYS_getpgrp 111 end +macro SYS_setsid 112 end +macro SYS_setreuid 113 end +macro SYS_setregid 114 end +macro SYS_getgroups 115 end +macro SYS_setgroups 116 end +macro SYS_setresuid 117 end +macro SYS_getresuid 118 end +macro SYS_setresgid 119 end +macro SYS_getresgid 120 end +macro SYS_getpgid 121 end +macro SYS_setfsuid 122 end +macro SYS_setfsgid 123 end +macro SYS_getsid 124 end +macro SYS_capget 125 end +macro SYS_capset 126 end +macro SYS_rt_sigpending 127 end +macro SYS_rt_sigtimedwait 128 end +macro SYS_rt_sigqueueinfo 129 end +macro SYS_rt_sigsuspend 130 end +macro SYS_sigaltstack 131 end +macro SYS_utime 132 end +macro SYS_mknod 133 end +macro SYS_uselib 134 end +macro SYS_personality 135 end +macro SYS_ustat 136 end +macro SYS_statfs 137 end +macro SYS_fstatfs 138 end +macro SYS_sysfs 139 end +macro SYS_getpriority 140 end +macro SYS_setpriority 141 end +macro SYS_sched_setparam 142 end +macro SYS_sched_getparam 143 end +macro SYS_sched_setscheduler 144 end +macro SYS_sched_getscheduler 145 end +macro SYS_sched_get_priority_max 146 end +macro SYS_sched_get_priority_min 147 end +macro SYS_sched_rr_get_interval 148 end +macro SYS_mlock 149 end +macro SYS_munlock 150 end +macro SYS_mlockall 151 end +macro SYS_munlockall 152 end +macro SYS_vhangup 153 end +macro SYS_modify_ldt 154 end +macro SYS_pivot_root 155 end +macro SYS__sysctl 156 end +macro SYS_prctl 157 end +macro SYS_arch_prctl 158 end +macro SYS_adjtimex 159 end +macro SYS_setrlimit 160 end +macro SYS_chroot 161 end +macro SYS_sync 162 end +macro SYS_acct 163 end +macro SYS_settimeofday 164 end +macro SYS_mount 165 end +macro SYS_umount2 166 end +macro SYS_swapon 167 end +macro SYS_swapoff 168 end +macro SYS_reboot 169 end +macro SYS_sethostname 170 end +macro SYS_setdomainname 171 end +macro SYS_iopl 172 end +macro SYS_ioperm 173 end +macro SYS_create_module 174 end +macro SYS_init_module 175 end +macro SYS_delete_module 176 end +macro SYS_get_kernel_syms 177 end +macro SYS_query_module 178 end +macro SYS_quotactl 179 end +macro SYS_nfsservctl 180 end +macro SYS_getpmsg 181 end +macro SYS_putpmsg 182 end +macro SYS_afs_syscall 183 end +macro SYS_tuxcall 184 end +macro SYS_security 185 end +macro SYS_gettid 186 end +macro SYS_readahead 187 end +macro SYS_setxattr 188 end +macro SYS_lsetxattr 189 end +macro SYS_fsetxattr 190 end +macro SYS_getxattr 191 end +macro SYS_lgetxattr 192 end +macro SYS_fgetxattr 193 end +macro SYS_listxattr 194 end +macro SYS_llistxattr 195 end +macro SYS_flistxattr 196 end +macro SYS_removexattr 197 end +macro SYS_lremovexattr 198 end +macro SYS_fremovexattr 199 end +macro SYS_tkill 200 end +macro SYS_time 201 end +macro SYS_futex 202 end +macro SYS_sched_setaffinity 203 end +macro SYS_sched_getaffinity 204 end +macro SYS_set_thread_area 205 end +macro SYS_io_setup 206 end +macro SYS_io_destroy 207 end +macro SYS_io_getevents 208 end +macro SYS_io_submit 209 end +macro SYS_io_cancel 210 end +macro SYS_get_thread_area 211 end +macro SYS_lookup_dcookie 212 end +macro SYS_epoll_create 213 end +macro SYS_epoll_ctl_old 214 end +macro SYS_epoll_wait_old 215 end +macro SYS_remap_file_pages 216 end +macro SYS_getdents64 217 end +macro SYS_set_tid_address 218 end +macro SYS_restart_syscall 219 end +macro SYS_semtimedop 220 end +macro SYS_fadvise64 221 end +macro SYS_timer_create 222 end +macro SYS_timer_settime 223 end +macro SYS_timer_gettime 224 end +macro SYS_timer_getoverrun 225 end +macro SYS_timer_delete 226 end +macro SYS_clock_settime 227 end +macro SYS_clock_gettime 228 end +macro SYS_clock_getres 229 end +macro SYS_clock_nanosleep 230 end +macro SYS_exit_group 231 end +macro SYS_epoll_wait 232 end +macro SYS_epoll_ctl 233 end +macro SYS_tgkill 234 end +macro SYS_utimes 235 end +macro SYS_vserver 236 end +macro SYS_mbind 237 end +macro SYS_set_mempolicy 238 end +macro SYS_get_mempolicy 239 end +macro SYS_mq_open 240 end +macro SYS_mq_unlink 241 end +macro SYS_mq_timedsend 242 end +macro SYS_mq_timedreceive 243 end +macro SYS_mq_notify 244 end +macro SYS_mq_getsetattr 245 end +macro SYS_kexec_load 246 end +macro SYS_waitid 247 end +macro SYS_add_key 248 end +macro SYS_request_key 249 end +macro SYS_keyctl 250 end +macro SYS_ioprio_set 251 end +macro SYS_ioprio_get 252 end +macro SYS_inotify_init 253 end +macro SYS_inotify_add_watch 254 end +macro SYS_inotify_rm_watch 255 end +macro SYS_migrate_pages 256 end +macro SYS_openat 257 end +macro SYS_mkdirat 258 end +macro SYS_mknodat 259 end +macro SYS_fchownat 260 end +macro SYS_futimesat 261 end +macro SYS_newfstatat 262 end +macro SYS_unlinkat 263 end +macro SYS_renameat 264 end +macro SYS_linkat 265 end +macro SYS_symlinkat 266 end +macro SYS_readlinkat 267 end +macro SYS_fchmodat 268 end +macro SYS_faccessat 269 end +macro SYS_pselect6 270 end +macro SYS_ppoll 271 end +macro SYS_unshare 272 end +macro SYS_set_robust_list 273 end +macro SYS_get_robust_list 274 end +macro SYS_splice 275 end +macro SYS_tee 276 end +macro SYS_sync_file_range 277 end +macro SYS_vmsplice 278 end +macro SYS_move_pages 279 end +macro SYS_utimensat 280 end +macro SYS_epoll_pwait 281 end +macro SYS_signalfd 282 end +macro SYS_timerfd_create 283 end +macro SYS_eventfd 284 end +macro SYS_fallocate 285 end +macro SYS_timerfd_settime 286 end +macro SYS_timerfd_gettime 287 end +macro SYS_accept4 288 end +macro SYS_signalfd4 289 end +macro SYS_eventfd2 290 end +macro SYS_epoll_create1 291 end +macro SYS_dup3 292 end +macro SYS_pipe2 293 end +macro SYS_inotify_init1 294 end +macro SYS_preadv 295 end +macro SYS_pwritev 296 end +macro SYS_rt_tgsigqueueinfo 297 end +macro SYS_perf_event_open 298 end +macro SYS_recvmmsg 299 end +macro SYS_fanotify_init 300 end +macro SYS_fanotify_mark 301 end +macro SYS_prlimit64 302 end +macro SYS_name_to_handle_at 303 end +macro SYS_open_by_handle_at 304 end +macro SYS_clock_adjtime 305 end +macro SYS_syncfs 306 end +macro SYS_sendmmsg 307 end +macro SYS_setns 308 end +macro SYS_getcpu 309 end +macro SYS_process_vm_readv 310 end +macro SYS_process_vm_writev 311 end +macro SYS_kcmp 312 end +macro SYS_finit_module 313 end \ No newline at end of file diff --git a/include/util.mcl b/include/util.mcl new file mode 100644 index 0000000..605bc8b --- /dev/null +++ b/include/util.mcl @@ -0,0 +1,15 @@ + +// Assert implementation +// args: [condition, str_len, str_ptr] +// @arg condition: Bool +// @arg str_len: Int +// @arg str_ptr: Ptr +// @ret NULL/NEVER +macro assert + rot + if else + "Assert failed: \"" eputs eputs + "\". Exiting!\n" eputs + 1 exit + end +end \ No newline at end of file diff --git a/src/compile/linux_x86_64.rs b/src/compile/linux_x86_64.rs index 592c77c..0ce18de 100644 --- a/src/compile/linux_x86_64.rs +++ b/src/compile/linux_x86_64.rs @@ -6,7 +6,7 @@ use crate::compile::commands::linux_x86_64_compile_and_link; use super::commands::linux_x86_64_run; -pub fn compile(tokens: Vec, args: Args) -> Result<()>{ +pub fn compile(tokens: Vec, args: Args) -> Result{ let mut of_c = PathBuf::from(&args.out_file); let (mut of_o, mut of_a) = if &args.out_file == &crate::DEFAULT_OUT_FILE.to_string() { let of_o = PathBuf::from("/tmp/mclang_comp.o"); @@ -405,8 +405,9 @@ pub fn compile(tokens: Vec, args: Args) -> Result<()>{ writer.flush()?; linux_x86_64_compile_and_link(&of_a, &of_o, &of_c, args.quiet)?; if args.run { - linux_x86_64_run(&of_c, vec![], args.quiet)?; + let c = linux_x86_64_run(&of_c, vec![], args.quiet)?; + return Ok(c); } - Ok(()) + Ok(0) } \ No newline at end of file diff --git a/src/constants.rs b/src/constants.rs index 4e79b4c..9b333b3 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -64,7 +64,7 @@ pub struct Operator { pub text: String, //? only used for OpType::PushStr pub addr: i64, //? only used for OpType::PushStr pub jmp: i32, - pub pos: (String, u32, u32) + pub loc: (String, u32, u32) } impl Operator { @@ -75,7 +75,7 @@ impl Operator { jmp: 0, addr: -1, text, - pos: (file, row, col) + loc: (file, row, col) } } diff --git a/src/interpret/linux_x86_64/mod.rs b/src/interpret/linux_x86_64/mod.rs index a502152..163ded6 100644 --- a/src/interpret/linux_x86_64/mod.rs +++ b/src/interpret/linux_x86_64/mod.rs @@ -14,7 +14,7 @@ fn stack_pop(stack: &mut Vec, pos: &(String, u32, u32)) -> Result { } } -pub fn run(tokens: Vec) -> Result<()>{ +pub fn run(tokens: Vec) -> Result{ let mut stack: Vec = Vec::new(); let mut ti = 0; let mut mem: Vec = vec![0; crate::compile::MEM_SZ as usize + crate::compile::STRING_SZ as usize]; @@ -25,7 +25,7 @@ pub fn run(tokens: Vec) -> Result<()>{ // } while ti < tokens.len() { let token = &tokens[ti]; - let pos = token.pos.clone(); + let pos = token.loc.clone(); // println!("{:?}", token.typ); match token.typ { @@ -272,5 +272,5 @@ pub fn run(tokens: Vec) -> Result<()>{ } - Ok(()) + Ok(0) } \ No newline at end of file diff --git a/src/lexer.rs b/src/lexer.rs index 4112c14..623cc6c 100644 --- a/src/lexer.rs +++ b/src/lexer.rs @@ -44,6 +44,8 @@ fn lex_line(text: String) -> Result> { let t = t.replace("\\n", "\n") .replace("\\t", "\t") .replace("\\r", "\r") + .replace("\\\'", "\'") + .replace("\\\"", "\"") .replace("\\0", "\0"); if !t.is_empty() { tokens.push((col, t.to_string(), TokenType::String)); @@ -100,5 +102,6 @@ pub fn lex(code: String, file: &String, args: Args, preprocessing: bool) -> Resu if preprocessing { tokens = preprocess(tokens, args)?; } + Ok(tokens) } \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 83f2922..7607b41 100644 --- a/src/main.rs +++ b/src/main.rs @@ -72,10 +72,7 @@ fn main() -> Result<()> { } }; - // for token in &tokens { - // println!("(f: {}, l: {}, c: {}, t: {})", token.file, token.line, token.col, token.text); - // } - + let mut parser = parser::Parser::new(tokens); let tokens = match parser.parse() { Ok(t) => t, @@ -84,26 +81,29 @@ fn main() -> Result<()> { return Ok(()); } }; - if args.compile && args.interpret { + + let c = if args.compile && args.interpret { error!("Cannot compile and interpret at the same time"); + 0 } else if args.interpret { match interpret::linux_x86_64::run(tokens) { - Ok(_) => (), + Ok(c) => c, Err(_) => { error!("Interpretation failed, exiting!"); - return Ok(()); + 1 } - }; + } } else if args.compile { match compile::linux_x86_64::compile(tokens, args) { - Ok(_) => (), + Ok(c) => c, Err(_) => { error!("Compilation failed, exiting!"); - return Ok(()); + 1 } - }; + } } else { error!("Did not choose to compile or to interpret, exiting"); - } - Ok(()) + 0 + }; + std::process::exit(c); } diff --git a/src/parser.rs b/src/parser.rs index 09e9cbf..7ddc525 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -15,7 +15,7 @@ pub fn cross_ref(mut program: Vec) -> Result> { OpType::Else => { let if_ip = stack.pop().unwrap(); if program[if_ip as usize].typ != OpType::If { - lerror!(&op.clone().pos,"'end' can only close 'if' blocks"); + lerror!(&op.clone().loc,"'end' can only close 'if' blocks"); return Err(eyre!("Bad block")); } @@ -37,7 +37,7 @@ pub fn cross_ref(mut program: Vec) -> Result> { program[ip].jmp = program[block_ip as usize].jmp; program[block_ip as usize].jmp = (ip + 1) as i32; } else { - lerror!(&op.clone().pos,"'end' can only close 'if' blocks"); + lerror!(&op.clone().loc,"'end' can only close 'if' blocks"); return Err(eyre!("")); } @@ -55,7 +55,7 @@ pub fn cross_ref(mut program: Vec) -> Result> { } if stack.len() > 0 { - lerror!(&program[stack.pop().expect("Empy stack") as usize].clone().pos,"Unclosed block"); + lerror!(&program[stack.pop().expect("Empy stack") as usize].clone().loc,"Unclosed block"); return Err(eyre!("Unclosed block")); } @@ -83,7 +83,7 @@ impl Parser { let pos = (token.file.clone(), token.line, token.col); match token.typ { TokenType::Word => { - let word_type = lookup_word(token.text.clone(), &pos)?; + let word_type = lookup_word(token.text.clone(), &pos); tokens.push(Operator::new(word_type, 0, token.text.clone(), token.file.clone(), token.line, token.col)); }, TokenType::Int => {// negative numbers not yet implemented @@ -103,7 +103,7 @@ impl Parser { } -pub fn lookup_word>(s: String, _pos: P) -> Result{ +pub fn lookup_word>(s: String, _pos: P) -> OpType { let lookup_table: HashMap<&str, OpType> = HashMap::from([ //stack ("print", OpType::Print), @@ -151,9 +151,9 @@ pub fn lookup_word>(s: String, _pos: P) -> ]); match lookup_table.get(s.as_str()) { - Some(v) => Ok(v.clone()), + Some(v) => v.clone(), None => { - Ok(OpType::None) + OpType::None } } } \ No newline at end of file diff --git a/src/preprocessor.rs b/src/preprocessor.rs index 7a8fe81..47502a0 100644 --- a/src/preprocessor.rs +++ b/src/preprocessor.rs @@ -6,7 +6,7 @@ use eyre::eyre; use crate::constants::{Token, Loc, OpType, TokenType}; use crate::lexer::lex; -use crate::{lerror, lnote, Args}; +use crate::{lerror, lnote, Args, warn}; use crate::parser::lookup_word; #[derive(Debug)] @@ -24,7 +24,7 @@ pub fn preprocess(tokens: Vec, args: Args) -> Result>{ while rtokens.len() > 0 { let token = rtokens.pop().unwrap(); - let op_type = lookup_word(token.text.clone(), &token.loc())?; + let op_type = lookup_word(token.text.clone(), &token.loc()); match token.clone() { _ if op_type == OpType::Macro => { if rtokens.len() == 0 { @@ -37,17 +37,19 @@ pub fn preprocess(tokens: Vec, args: Args) -> Result>{ lerror!(¯o_name.loc(), "Bad macro name, expected {} but found {}", TokenType::Word.human(), macro_name.typ.human()); return Err(eyre!("")); } - let word = lookup_word(macro_name.text.clone(), ¯o_name.loc())?; + let word = lookup_word(macro_name.text.clone(), ¯o_name.loc()); if word != OpType::None { lerror!(¯o_name.loc(), "Macro name cannot be a built in word, got '{}'", word.human()); return Err(eyre!("")); } - if crate::constants::ALLOW_MACRO_REDEFINITION { - if macros.get(¯o_name.text.clone()).is_some() { + if macros.get(¯o_name.text.clone()).is_some() { + if crate::constants::ALLOW_MACRO_REDEFINITION { lerror!(¯o_name.loc(), "Macro redefinition is not allowed"); lnote!(¯os.get(¯o_name.text.clone()).unwrap().loc, "First definition here"); return Err(eyre!("")); + } else { + //TODO: somehow warn about redefinition of only built in macros } } @@ -56,7 +58,7 @@ pub fn preprocess(tokens: Vec, args: Args) -> Result>{ let mut depth = 0; while rtokens.len() > 0 { let t = rtokens.pop().unwrap(); - let typ = lookup_word(t.text.clone(), &t.loc())?; + let typ = lookup_word(t.text.clone(), &t.loc()); if typ == OpType::End && depth == 0 { break; } else if typ == OpType::End && depth != 0 { @@ -123,12 +125,31 @@ pub fn preprocess(tokens: Vec, args: Args) -> Result>{ } } - program = expand_macros(program, macros)?; + //* Feel free to fix this horrifying shit + //* i wanna kms + let mut times = 0; + while program.iter().map(|f| { + if f.typ == TokenType::Word { + lookup_word(f.text.clone(), &f.loc()) + } else { + OpType::PushInt // i hate myself, this is a randomly picked optype so its happy and works + } + + }).collect::>().contains(&OpType::None){ + + if times >= 50 { + warn!("File import depth maxed out, if the program crashes try reducing the import depth, good luck youll need it"); + break + } + program = expand_macros(program, ¯os)?; + times += 1; + } + Ok(program) } -pub fn expand_macros(tokens: Vec, macros: HashMap) -> Result> { +pub fn expand_macros(tokens: Vec, macros: &HashMap) -> Result> { let mut program: Vec = Vec::new(); let mut rtokens = tokens.clone(); @@ -136,7 +157,7 @@ pub fn expand_macros(tokens: Vec, macros: HashMap) -> Resu while rtokens.len() > 0 { let op = rtokens.pop().unwrap(); - let op_type = lookup_word(op.text.clone(), &op.loc())?; + let op_type = lookup_word(op.text.clone(), &op.loc()); if op.typ == TokenType::Word { match op_type { OpType::None => { diff --git a/test.mcl b/test.mcl index a4bde0d..a54b606 100644 --- a/test.mcl +++ b/test.mcl @@ -1,3 +1,6 @@ include "io.mcl" +include "util.mcl" -"HEnlo world!\n" write \ No newline at end of file +"HEnlo world!\n" puts + +2 2 = "i suck at math" assert \ No newline at end of file