started implementing stdlib
This commit is contained in:
parent
2d5e94608c
commit
d536bfcf31
42
include/io.mcl
Normal file
42
include/io.mcl
Normal file
|
@ -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
|
||||
|
322
include/linux.mcl
Normal file
322
include/linux.mcl
Normal file
|
@ -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
|
15
include/util.mcl
Normal file
15
include/util.mcl
Normal file
|
@ -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
|
|
@ -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<Operator>, args: Args) -> Result<()>{
|
||||
pub fn compile(tokens: Vec<Operator>, args: Args) -> Result<i32>{
|
||||
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<Operator>, 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)
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ fn stack_pop(stack: &mut Vec<u64>, pos: &(String, u32, u32)) -> Result<u64> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn run(tokens: Vec<crate::constants::Operator>) -> Result<()>{
|
||||
pub fn run(tokens: Vec<crate::constants::Operator>) -> Result<i32>{
|
||||
let mut stack: Vec<u64> = Vec::new();
|
||||
let mut ti = 0;
|
||||
let mut mem: Vec<u8> = vec![0; crate::compile::MEM_SZ as usize + crate::compile::STRING_SZ as usize];
|
||||
|
@ -25,7 +25,7 @@ pub fn run(tokens: Vec<crate::constants::Operator>) -> 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<crate::constants::Operator>) -> Result<()>{
|
|||
}
|
||||
|
||||
|
||||
Ok(())
|
||||
Ok(0)
|
||||
}
|
|
@ -44,6 +44,8 @@ fn lex_line(text: String) -> Result<Vec<(u32, String, TokenType)>> {
|
|||
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)
|
||||
}
|
24
src/main.rs
24
src/main.rs
|
@ -72,9 +72,6 @@ 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() {
|
||||
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ pub fn cross_ref(mut program: Vec<Operator>) -> Result<Vec<Operator>> {
|
|||
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<Operator>) -> Result<Vec<Operator>> {
|
|||
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<Operator>) -> Result<Vec<Operator>> {
|
|||
|
||||
}
|
||||
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<P: Deref<Target = (String, u32, u32)>>(s: String, _pos: P) -> Result<OpType>{
|
||||
pub fn lookup_word<P: Deref<Target = (String, u32, u32)>>(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<P: Deref<Target = (String, u32, u32)>>(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
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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<Token>, args: Args) -> Result<Vec<Token>>{
|
|||
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<Token>, args: Args) -> Result<Vec<Token>>{
|
|||
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 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<Token>, args: Args) -> Result<Vec<Token>>{
|
|||
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<Token>, args: Args) -> Result<Vec<Token>>{
|
|||
}
|
||||
}
|
||||
|
||||
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::<Vec<OpType>>().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<Token>, macros: HashMap<String, Macro>) -> Result<Vec<Token>> {
|
||||
pub fn expand_macros(tokens: Vec<Token>, macros: &HashMap<String, Macro>) -> Result<Vec<Token>> {
|
||||
let mut program: Vec<Token> = Vec::new();
|
||||
|
||||
let mut rtokens = tokens.clone();
|
||||
|
@ -136,7 +157,7 @@ pub fn expand_macros(tokens: Vec<Token>, macros: HashMap<String, Macro>) -> 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 => {
|
||||
|
|
Loading…
Reference in New Issue
Block a user