not working very well with std lib but working standalone ig

This commit is contained in:
MCorange 2023-04-11 16:24:52 +03:00
parent 9c84033d3f
commit 63636e1f83
19 changed files with 1115 additions and 741 deletions

Binary file not shown.

View File

@ -37,6 +37,6 @@
}, },
"dependencies": { "dependencies": {
"generator-code": "^1.7.4", "generator-code": "^1.7.4",
"vsce": "^2.15.0" "@vscode/vsce": "^2.15.0"
} }
} }

View File

@ -53,7 +53,7 @@
{ {
"name": "keyword.declaration.mclang", "name": "keyword.declaration.mclang",
"match": "(?<=\\s|^)(macro|memory|fn|const|in|inline|include|assert|offset|addr-of|call-like|reset|int|ptr|bool|addr|--|let|peek)(?:\\s|$)" "match": "(?<=\\s|^)(macro|memory|fn|const|in|inline|include|assert|offset|addr-of|call-like|reset|let|peek|with|returns)(?:\\s|$)"
}, },
{ {
"name": "keyword.control.mclang", "name": "keyword.control.mclang",
@ -123,7 +123,7 @@
"patterns": [ "patterns": [
{ {
"name": "variable.name.source.mclang", "name": "variable.name.source.mclang",
"match": "(?<=^|\\s)(\\+|-|\\*|max|divmod|print|=|>|<|>=|<=|!=|>>|<<|\\||&|not|dup|swap|drop|over|rot|argc|argv|here|syscall0|syscall1|syscall2|syscall3|syscall4|syscall5|syscall6|mem|\\?\\?\\?)(?=>$|\\s)" "match": "(?<=^|\\s)(\\+|-|\\*|int|ptr|bool|addr|max|divmod|print|=|>|<|>=|<=|!=|>>|<<|\\||&|not|dup|swap|drop|over|rot|argc|argv|here|syscall0|syscall1|syscall2|syscall3|syscall4|syscall5|syscall6|mem|\\?\\?\\?)(?=>$|\\s)"
} }
] ]
}, },

View File

@ -1,5 +1 @@
macro __compat__ // todo: add some sort of macro
macro !8 load8 end
macro @8 store8 end
end

View File

@ -1,19 +1,18 @@
const FS_O_APPEND 1024 end // append to existing file
macro FS_O_APPEND 1024 end // append to existing file const FS_O_ASYNC 8192 end // use signal-driven IO
macro FS_O_ASYNC 8192 end // use signal-driven IO const FS_O_CLOEXEC 524288 end // use close-on-exec (avoid race conditions and lock contentions)
macro FS_O_CLOEXEC 524288 end // use close-on-exec (avoid race conditions and lock contentions) const FS_O_CREAT 64 end // create file if it doesnt exist
macro FS_O_CREAT 64 end // create file if it doesnt exist const FS_O_DIRECT 16384 end // bypass cache (slower)
macro FS_O_DIRECT 16384 end // bypass cache (slower) const FS_O_DIRECTORY 65536 end // fail if pathname isnt a directory
macro FS_O_DIRECTORY 65536 end // fail if pathname isnt a directory const FS_O_DSYNC 4096 end // ensure output is sent to hardware and metadata written before return
macro FS_O_DSYNC 4096 end // ensure output is sent to hardware and metadata written before return const FS_O_EXCL 128 end // ensure creation of file
macro FS_O_EXCL 128 end // ensure creation of file const FS_O_LARGEFILE 0 end // allows use of file sizes represented by off64_t
macro FS_O_LARGEFILE 0 end // allows use of file sizes represented by off64_t const FS_O_NOATIME 262144 end // do not increment access time upon open
macro FS_O_NOATIME 262144 end // do not increment access time upon open const FS_O_NOCTTY 256 end // if pathname is a terminal device, dont become controlling terminal
macro FS_O_NOCTTY 256 end // if pathname is a terminal device, dont become controlling terminal const FS_O_NOFOLLOW 131072 end // fail if pathname is symbolic link
macro FS_O_NOFOLLOW 131072 end // fail if pathname is symbolic link const FS_O_NONBLOCK 2048 end // if possible, open file with non-blocking IO
macro FS_O_NONBLOCK 2048 end // if possible, open file with non-blocking IO const FS_O_NDELAY 2048 end // same as O_NONBLOCK
macro FS_O_NDELAY 2048 end // same as O_NONBLOCK const 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_PATH 2097152 end // open descriptor for obtaining permissions and status of a file but does not allow read/write operations const FS_O_SYNC 1052672 end // wait for IO to complete before returning
macro FS_O_SYNC 1052672 end // wait for IO to complete before returning const FS_O_TMPFILE 4259840 end // create an unnamed, unreachable (via any other open call) temporary file
macro FS_O_TMPFILE 4259840 end // create an unnamed, unreachable (via any other open call) temporary file const FS_O_TRUNC 512 end // if file exists, ovewrite it (careful!)
macro FS_O_TRUNC 512 end // if file exists, ovewrite it (careful!)

View File

@ -1,16 +1,16 @@
macro NULL 0 end const NULL 0 end
macro false 0 end const false 0 end
macro true 1 end const true 1 end
macro div divmod drop end fn div with int int returns int int divmod drop end
macro mod divmod swap drop end fn mod with int int returns int int divmod swap drop end
macro / div end fn / with int int returns int int div end
macro % mod end fn % with int int returns int int mod end
macro 2dup over over end fn 2dup with any any returns any over over end
macro 2drop drop drop end fn 2drop with any any returns any drop drop end
macro sizeof(u64) 8 end const sizeof(u64) 8 end
macro sizeof(u32) 4 end const sizeof(u32) 4 end
macro sizeof(u16) 2 end const sizeof(u16) 2 end
macro sizeof(u8) 1 end const sizeof(u8) 1 end

View File

@ -5,7 +5,7 @@
// @arg buff_ptr: Ptr - pointer to the buffer to write // @arg buff_ptr: Ptr - pointer to the buffer to write
// @arg fd: Int - file descriptor // @arg fd: Int - file descriptor
// @ret Int // @ret Int
fn write do fn write with int ptr int returns int do
SYS_write syscall3 SYS_write syscall3
end end
@ -15,7 +15,7 @@ end
// @arg buff_ptr: Ptr - pointer to the buffer to write // @arg buff_ptr: Ptr - pointer to the buffer to write
// @arg fd: Int - file descriptor // @arg fd: Int - file descriptor
// @ret Int // @ret Int
fn read do fn read with int ptr int returns int do
SYS_read syscall3 SYS_read syscall3
end end
@ -25,7 +25,7 @@ end
// @arg buff_size: Int - number of bytes to write // @arg buff_size: Int - number of bytes to write
// @arg buff_ptr: Ptr - pointer to the buffer to write // @arg buff_ptr: Ptr - pointer to the buffer to write
// @ret NULL // @ret NULL
fn puts do fn puts with int ptr returns null do
STDOUT write drop STDOUT write drop
end end
@ -34,7 +34,7 @@ end
// @arg buff_size: Int - number of bytes to write // @arg buff_size: Int - number of bytes to write
// @arg buff_ptr: Ptr - pointer to the buffer to write // @arg buff_ptr: Ptr - pointer to the buffer to write
// @ret NULL // @ret NULL
fn eputs do fn eputs with int ptr returns null do
STDOUT write drop STDOUT write drop
end end
@ -44,7 +44,7 @@ end
// args: [exit_code] // args: [exit_code]
// @arg exit_code: Int // @arg exit_code: Int
// @ret NULL/NEVER // @ret NULL/NEVER
fn exit do fn exit with int returns null do
SYS_exit syscall1 drop SYS_exit syscall1 drop
end end

View File

@ -1,322 +1,322 @@
// file descriptors // file descriptors
macro STDIN 0 end const STDIN 0 end
macro STDOUT 1 end const STDOUT 1 end
macro STDERR 2 end const STDERR 2 end
// syscalls // syscalls
macro SYS_read 0 end const SYS_read 0 end
macro SYS_write 1 end const SYS_write 1 end
macro SYS_open 2 end const SYS_open 2 end
macro SYS_close 3 end const SYS_close 3 end
macro SYS_stat 4 end const SYS_stat 4 end
macro SYS_fstat 5 end const SYS_fstat 5 end
macro SYS_lstat 6 end const SYS_lstat 6 end
macro SYS_poll 7 end const SYS_poll 7 end
macro SYS_lseek 8 end const SYS_lseek 8 end
macro SYS_mmap 9 end const SYS_mmap 9 end
macro SYS_mprotect 10 end const SYS_mprotect 10 end
macro SYS_munmap 11 end const SYS_munmap 11 end
macro SYS_brk 12 end const SYS_brk 12 end
macro SYS_rt_sigaction 13 end const SYS_rt_sigaction 13 end
macro SYS_rt_sigprocmask 14 end const SYS_rt_sigprocmask 14 end
macro SYS_rt_sigreturn 15 end const SYS_rt_sigreturn 15 end
macro SYS_ioctl 16 end const SYS_ioctl 16 end
macro SYS_pread64 17 end const SYS_pread64 17 end
macro SYS_pwrite64 18 end const SYS_pwrite64 18 end
macro SYS_readv 19 end const SYS_readv 19 end
macro SYS_writev 20 end const SYS_writev 20 end
macro SYS_access 21 end const SYS_access 21 end
macro SYS_pipe 22 end const SYS_pipe 22 end
macro SYS_select 23 end const SYS_select 23 end
macro SYS_sched_yield 24 end const SYS_sched_yield 24 end
macro SYS_mremap 25 end const SYS_mremap 25 end
macro SYS_msync 26 end const SYS_msync 26 end
macro SYS_mincore 27 end const SYS_mincore 27 end
macro SYS_madvise 28 end const SYS_madvise 28 end
macro SYS_shmget 29 end const SYS_shmget 29 end
macro SYS_shmat 30 end const SYS_shmat 30 end
macro SYS_shmctl 31 end const SYS_shmctl 31 end
macro SYS_dup 32 end const SYS_dup 32 end
macro SYS_dup2 33 end const SYS_dup2 33 end
macro SYS_pause 34 end const SYS_pause 34 end
macro SYS_nanosleep 35 end const SYS_nanosleep 35 end
macro SYS_getitimer 36 end const SYS_getitimer 36 end
macro SYS_alarm 37 end const SYS_alarm 37 end
macro SYS_setitimer 38 end const SYS_setitimer 38 end
macro SYS_getpid 39 end const SYS_getpid 39 end
macro SYS_sendfile 40 end const SYS_sendfile 40 end
macro SYS_socket 41 end const SYS_socket 41 end
macro SYS_connect 42 end const SYS_connect 42 end
macro SYS_accept 43 end const SYS_accept 43 end
macro SYS_sendto 44 end const SYS_sendto 44 end
macro SYS_recvfrom 45 end const SYS_recvfrom 45 end
macro SYS_sendmsg 46 end const SYS_sendmsg 46 end
macro SYS_recvmsg 47 end const SYS_recvmsg 47 end
macro SYS_shutdown 48 end const SYS_shutdown 48 end
macro SYS_bind 49 end const SYS_bind 49 end
macro SYS_listen 50 end const SYS_listen 50 end
macro SYS_getsockname 51 end const SYS_getsockname 51 end
macro SYS_getpeername 52 end const SYS_getpeername 52 end
macro SYS_socketpair 53 end const SYS_socketpair 53 end
macro SYS_setsockopt 54 end const SYS_setsockopt 54 end
macro SYS_getsockopt 55 end const SYS_getsockopt 55 end
macro SYS_clone 56 end const SYS_clone 56 end
macro SYS_fork 57 end const SYS_fork 57 end
macro SYS_vfork 58 end const SYS_vfork 58 end
macro SYS_execve 59 end const SYS_execve 59 end
macro SYS_exit 60 end const SYS_exit 60 end
macro SYS_wait4 61 end const SYS_wait4 61 end
macro SYS_kill 62 end const SYS_kill 62 end
macro SYS_uname 63 end const SYS_uname 63 end
macro SYS_semget 64 end const SYS_semget 64 end
macro SYS_semop 65 end const SYS_semop 65 end
macro SYS_semctl 66 end const SYS_semctl 66 end
macro SYS_shmdt 67 end const SYS_shmdt 67 end
macro SYS_msgget 68 end const SYS_msgget 68 end
macro SYS_msgsnd 69 end const SYS_msgsnd 69 end
macro SYS_msgrcv 70 end const SYS_msgrcv 70 end
macro SYS_msgctl 71 end const SYS_msgctl 71 end
macro SYS_fcntl 72 end const SYS_fcntl 72 end
macro SYS_flock 73 end const SYS_flock 73 end
macro SYS_fsync 74 end const SYS_fsync 74 end
macro SYS_fdatasync 75 end const SYS_fdatasync 75 end
macro SYS_truncate 76 end const SYS_truncate 76 end
macro SYS_ftruncate 77 end const SYS_ftruncate 77 end
macro SYS_getdents 78 end const SYS_getdents 78 end
macro SYS_getcwd 79 end const SYS_getcwd 79 end
macro SYS_chdir 80 end const SYS_chdir 80 end
macro SYS_fchdir 81 end const SYS_fchdir 81 end
macro SYS_rename 82 end const SYS_rename 82 end
macro SYS_mkdir 83 end const SYS_mkdir 83 end
macro SYS_rmdir 84 end const SYS_rmdir 84 end
macro SYS_creat 85 end const SYS_creat 85 end
macro SYS_link 86 end const SYS_link 86 end
macro SYS_unlink 87 end const SYS_unlink 87 end
macro SYS_symlink 88 end const SYS_symlink 88 end
macro SYS_readlink 89 end const SYS_readlink 89 end
macro SYS_chmod 90 end const SYS_chmod 90 end
macro SYS_fchmod 91 end const SYS_fchmod 91 end
macro SYS_chown 92 end const SYS_chown 92 end
macro SYS_fchown 93 end const SYS_fchown 93 end
macro SYS_lchown 94 end const SYS_lchown 94 end
macro SYS_umask 95 end const SYS_umask 95 end
macro SYS_gettimeofday 96 end const SYS_gettimeofday 96 end
macro SYS_getrlimit 97 end const SYS_getrlimit 97 end
macro SYS_getrusage 98 end const SYS_getrusage 98 end
macro SYS_sysinfo 99 end const SYS_sysinfo 99 end
macro SYS_times 100 end const SYS_times 100 end
macro SYS_ptrace 101 end const SYS_ptrace 101 end
macro SYS_getuid 102 end const SYS_getuid 102 end
macro SYS_syslog 103 end const SYS_syslog 103 end
macro SYS_getgid 104 end const SYS_getgid 104 end
macro SYS_setuid 105 end const SYS_setuid 105 end
macro SYS_setgid 106 end const SYS_setgid 106 end
macro SYS_geteuid 107 end const SYS_geteuid 107 end
macro SYS_getegid 108 end const SYS_getegid 108 end
macro SYS_setpgid 109 end const SYS_setpgid 109 end
macro SYS_getppid 110 end const SYS_getppid 110 end
macro SYS_getpgrp 111 end const SYS_getpgrp 111 end
macro SYS_setsid 112 end const SYS_setsid 112 end
macro SYS_setreuid 113 end const SYS_setreuid 113 end
macro SYS_setregid 114 end const SYS_setregid 114 end
macro SYS_getgroups 115 end const SYS_getgroups 115 end
macro SYS_setgroups 116 end const SYS_setgroups 116 end
macro SYS_setresuid 117 end const SYS_setresuid 117 end
macro SYS_getresuid 118 end const SYS_getresuid 118 end
macro SYS_setresgid 119 end const SYS_setresgid 119 end
macro SYS_getresgid 120 end const SYS_getresgid 120 end
macro SYS_getpgid 121 end const SYS_getpgid 121 end
macro SYS_setfsuid 122 end const SYS_setfsuid 122 end
macro SYS_setfsgid 123 end const SYS_setfsgid 123 end
macro SYS_getsid 124 end const SYS_getsid 124 end
macro SYS_capget 125 end const SYS_capget 125 end
macro SYS_capset 126 end const SYS_capset 126 end
macro SYS_rt_sigpending 127 end const SYS_rt_sigpending 127 end
macro SYS_rt_sigtimedwait 128 end const SYS_rt_sigtimedwait 128 end
macro SYS_rt_sigqueueinfo 129 end const SYS_rt_sigqueueinfo 129 end
macro SYS_rt_sigsuspend 130 end const SYS_rt_sigsuspend 130 end
macro SYS_sigaltstack 131 end const SYS_sigaltstack 131 end
macro SYS_utime 132 end const SYS_utime 132 end
macro SYS_mknod 133 end const SYS_mknod 133 end
macro SYS_uselib 134 end const SYS_uselib 134 end
macro SYS_personality 135 end const SYS_personality 135 end
macro SYS_ustat 136 end const SYS_ustat 136 end
macro SYS_statfs 137 end const SYS_statfs 137 end
macro SYS_fstatfs 138 end const SYS_fstatfs 138 end
macro SYS_sysfs 139 end const SYS_sysfs 139 end
macro SYS_getpriority 140 end const SYS_getpriority 140 end
macro SYS_setpriority 141 end const SYS_setpriority 141 end
macro SYS_sched_setparam 142 end const SYS_sched_setparam 142 end
macro SYS_sched_getparam 143 end const SYS_sched_getparam 143 end
macro SYS_sched_setscheduler 144 end const SYS_sched_setscheduler 144 end
macro SYS_sched_getscheduler 145 end const SYS_sched_getscheduler 145 end
macro SYS_sched_get_priority_max 146 end const SYS_sched_get_priority_max 146 end
macro SYS_sched_get_priority_min 147 end const SYS_sched_get_priority_min 147 end
macro SYS_sched_rr_get_interval 148 end const SYS_sched_rr_get_interval 148 end
macro SYS_mlock 149 end const SYS_mlock 149 end
macro SYS_munlock 150 end const SYS_munlock 150 end
macro SYS_mlockall 151 end const SYS_mlockall 151 end
macro SYS_munlockall 152 end const SYS_munlockall 152 end
macro SYS_vhangup 153 end const SYS_vhangup 153 end
macro SYS_modify_ldt 154 end const SYS_modify_ldt 154 end
macro SYS_pivot_root 155 end const SYS_pivot_root 155 end
macro SYS__sysctl 156 end const SYS__sysctl 156 end
macro SYS_prctl 157 end const SYS_prctl 157 end
macro SYS_arch_prctl 158 end const SYS_arch_prctl 158 end
macro SYS_adjtimex 159 end const SYS_adjtimex 159 end
macro SYS_setrlimit 160 end const SYS_setrlimit 160 end
macro SYS_chroot 161 end const SYS_chroot 161 end
macro SYS_sync 162 end const SYS_sync 162 end
macro SYS_acct 163 end const SYS_acct 163 end
macro SYS_settimeofday 164 end const SYS_settimeofday 164 end
macro SYS_mount 165 end const SYS_mount 165 end
macro SYS_umount2 166 end const SYS_umount2 166 end
macro SYS_swapon 167 end const SYS_swapon 167 end
macro SYS_swapoff 168 end const SYS_swapoff 168 end
macro SYS_reboot 169 end const SYS_reboot 169 end
macro SYS_sethostname 170 end const SYS_sethostname 170 end
macro SYS_setdomainname 171 end const SYS_setdomainname 171 end
macro SYS_iopl 172 end const SYS_iopl 172 end
macro SYS_ioperm 173 end const SYS_ioperm 173 end
macro SYS_create_module 174 end const SYS_create_module 174 end
macro SYS_init_module 175 end const SYS_init_module 175 end
macro SYS_delete_module 176 end const SYS_delete_module 176 end
macro SYS_get_kernel_syms 177 end const SYS_get_kernel_syms 177 end
macro SYS_query_module 178 end const SYS_query_module 178 end
macro SYS_quotactl 179 end const SYS_quotactl 179 end
macro SYS_nfsservctl 180 end const SYS_nfsservctl 180 end
macro SYS_getpmsg 181 end const SYS_getpmsg 181 end
macro SYS_putpmsg 182 end const SYS_putpmsg 182 end
macro SYS_afs_syscall 183 end const SYS_afs_syscall 183 end
macro SYS_tuxcall 184 end const SYS_tuxcall 184 end
macro SYS_security 185 end const SYS_security 185 end
macro SYS_gettid 186 end const SYS_gettid 186 end
macro SYS_readahead 187 end const SYS_readahead 187 end
macro SYS_setxattr 188 end const SYS_setxattr 188 end
macro SYS_lsetxattr 189 end const SYS_lsetxattr 189 end
macro SYS_fsetxattr 190 end const SYS_fsetxattr 190 end
macro SYS_getxattr 191 end const SYS_getxattr 191 end
macro SYS_lgetxattr 192 end const SYS_lgetxattr 192 end
macro SYS_fgetxattr 193 end const SYS_fgetxattr 193 end
macro SYS_listxattr 194 end const SYS_listxattr 194 end
macro SYS_llistxattr 195 end const SYS_llistxattr 195 end
macro SYS_flistxattr 196 end const SYS_flistxattr 196 end
macro SYS_removexattr 197 end const SYS_removexattr 197 end
macro SYS_lremovexattr 198 end const SYS_lremovexattr 198 end
macro SYS_fremovexattr 199 end const SYS_fremovexattr 199 end
macro SYS_tkill 200 end const SYS_tkill 200 end
macro SYS_time 201 end const SYS_time 201 end
macro SYS_futex 202 end const SYS_futex 202 end
macro SYS_sched_setaffinity 203 end const SYS_sched_setaffinity 203 end
macro SYS_sched_getaffinity 204 end const SYS_sched_getaffinity 204 end
macro SYS_set_thread_area 205 end const SYS_set_thread_area 205 end
macro SYS_io_setup 206 end const SYS_io_setup 206 end
macro SYS_io_destroy 207 end const SYS_io_destroy 207 end
macro SYS_io_getevents 208 end const SYS_io_getevents 208 end
macro SYS_io_submit 209 end const SYS_io_submit 209 end
macro SYS_io_cancel 210 end const SYS_io_cancel 210 end
macro SYS_get_thread_area 211 end const SYS_get_thread_area 211 end
macro SYS_lookup_dcookie 212 end const SYS_lookup_dcookie 212 end
macro SYS_epoll_create 213 end const SYS_epoll_create 213 end
macro SYS_epoll_ctl_old 214 end const SYS_epoll_ctl_old 214 end
macro SYS_epoll_wait_old 215 end const SYS_epoll_wait_old 215 end
macro SYS_remap_file_pages 216 end const SYS_remap_file_pages 216 end
macro SYS_getdents64 217 end const SYS_getdents64 217 end
macro SYS_set_tid_address 218 end const SYS_set_tid_address 218 end
macro SYS_restart_syscall 219 end const SYS_restart_syscall 219 end
macro SYS_semtimedop 220 end const SYS_semtimedop 220 end
macro SYS_fadvise64 221 end const SYS_fadvise64 221 end
macro SYS_timer_create 222 end const SYS_timer_create 222 end
macro SYS_timer_settime 223 end const SYS_timer_settime 223 end
macro SYS_timer_gettime 224 end const SYS_timer_gettime 224 end
macro SYS_timer_getoverrun 225 end const SYS_timer_getoverrun 225 end
macro SYS_timer_delete 226 end const SYS_timer_delete 226 end
macro SYS_clock_settime 227 end const SYS_clock_settime 227 end
macro SYS_clock_gettime 228 end const SYS_clock_gettime 228 end
macro SYS_clock_getres 229 end const SYS_clock_getres 229 end
macro SYS_clock_nanosleep 230 end const SYS_clock_nanosleep 230 end
macro SYS_exit_group 231 end const SYS_exit_group 231 end
macro SYS_epoll_wait 232 end const SYS_epoll_wait 232 end
macro SYS_epoll_ctl 233 end const SYS_epoll_ctl 233 end
macro SYS_tgkill 234 end const SYS_tgkill 234 end
macro SYS_utimes 235 end const SYS_utimes 235 end
macro SYS_vserver 236 end const SYS_vserver 236 end
macro SYS_mbind 237 end const SYS_mbind 237 end
macro SYS_set_mempolicy 238 end const SYS_set_mempolicy 238 end
macro SYS_get_mempolicy 239 end const SYS_get_mempolicy 239 end
macro SYS_mq_open 240 end const SYS_mq_open 240 end
macro SYS_mq_unlink 241 end const SYS_mq_unlink 241 end
macro SYS_mq_timedsend 242 end const SYS_mq_timedsend 242 end
macro SYS_mq_timedreceive 243 end const SYS_mq_timedreceive 243 end
macro SYS_mq_notify 244 end const SYS_mq_notify 244 end
macro SYS_mq_getsetattr 245 end const SYS_mq_getsetattr 245 end
macro SYS_kexec_load 246 end const SYS_kexec_load 246 end
macro SYS_waitid 247 end const SYS_waitid 247 end
macro SYS_add_key 248 end const SYS_add_key 248 end
macro SYS_request_key 249 end const SYS_request_key 249 end
macro SYS_keyctl 250 end const SYS_keyctl 250 end
macro SYS_ioprio_set 251 end const SYS_ioprio_set 251 end
macro SYS_ioprio_get 252 end const SYS_ioprio_get 252 end
macro SYS_inotify_init 253 end const SYS_inotify_init 253 end
macro SYS_inotify_add_watch 254 end const SYS_inotify_add_watch 254 end
macro SYS_inotify_rm_watch 255 end const SYS_inotify_rm_watch 255 end
macro SYS_migrate_pages 256 end const SYS_migrate_pages 256 end
macro SYS_openat 257 end const SYS_openat 257 end
macro SYS_mkdirat 258 end const SYS_mkdirat 258 end
macro SYS_mknodat 259 end const SYS_mknodat 259 end
macro SYS_fchownat 260 end const SYS_fchownat 260 end
macro SYS_futimesat 261 end const SYS_futimesat 261 end
macro SYS_newfstatat 262 end const SYS_newfstatat 262 end
macro SYS_unlinkat 263 end const SYS_unlinkat 263 end
macro SYS_renameat 264 end const SYS_renameat 264 end
macro SYS_linkat 265 end const SYS_linkat 265 end
macro SYS_symlinkat 266 end const SYS_symlinkat 266 end
macro SYS_readlinkat 267 end const SYS_readlinkat 267 end
macro SYS_fchmodat 268 end const SYS_fchmodat 268 end
macro SYS_faccessat 269 end const SYS_faccessat 269 end
macro SYS_pselect6 270 end const SYS_pselect6 270 end
macro SYS_ppoll 271 end const SYS_ppoll 271 end
macro SYS_unshare 272 end const SYS_unshare 272 end
macro SYS_set_robust_list 273 end const SYS_set_robust_list 273 end
macro SYS_get_robust_list 274 end const SYS_get_robust_list 274 end
macro SYS_splice 275 end const SYS_splice 275 end
macro SYS_tee 276 end const SYS_tee 276 end
macro SYS_sync_file_range 277 end const SYS_sync_file_range 277 end
macro SYS_vmsplice 278 end const SYS_vmsplice 278 end
macro SYS_move_pages 279 end const SYS_move_pages 279 end
macro SYS_utimensat 280 end const SYS_utimensat 280 end
macro SYS_epoll_pwait 281 end const SYS_epoll_pwait 281 end
macro SYS_signalfd 282 end const SYS_signalfd 282 end
macro SYS_timerfd_create 283 end const SYS_timerfd_create 283 end
macro SYS_eventfd 284 end const SYS_eventfd 284 end
macro SYS_fallocate 285 end const SYS_fallocate 285 end
macro SYS_timerfd_settime 286 end const SYS_timerfd_settime 286 end
macro SYS_timerfd_gettime 287 end const SYS_timerfd_gettime 287 end
macro SYS_accept4 288 end const SYS_accept4 288 end
macro SYS_signalfd4 289 end const SYS_signalfd4 289 end
macro SYS_eventfd2 290 end const SYS_eventfd2 290 end
macro SYS_epoll_create1 291 end const SYS_epoll_create1 291 end
macro SYS_dup3 292 end const SYS_dup3 292 end
macro SYS_pipe2 293 end const SYS_pipe2 293 end
macro SYS_inotify_init1 294 end const SYS_inotify_init1 294 end
macro SYS_preadv 295 end const SYS_preadv 295 end
macro SYS_pwritev 296 end const SYS_pwritev 296 end
macro SYS_rt_tgsigqueueinfo 297 end const SYS_rt_tgsigqueueinfo 297 end
macro SYS_perf_event_open 298 end const SYS_perf_event_open 298 end
macro SYS_recvmmsg 299 end const SYS_recvmmsg 299 end
macro SYS_fanotify_init 300 end const SYS_fanotify_init 300 end
macro SYS_fanotify_mark 301 end const SYS_fanotify_mark 301 end
macro SYS_prlimit64 302 end const SYS_prlimit64 302 end
macro SYS_name_to_handle_at 303 end const SYS_name_to_handle_at 303 end
macro SYS_open_by_handle_at 304 end const SYS_open_by_handle_at 304 end
macro SYS_clock_adjtime 305 end const SYS_clock_adjtime 305 end
macro SYS_syncfs 306 end const SYS_syncfs 306 end
macro SYS_sendmmsg 307 end const SYS_sendmmsg 307 end
macro SYS_setns 308 end const SYS_setns 308 end
macro SYS_getcpu 309 end const SYS_getcpu 309 end
macro SYS_process_vm_readv 310 end const SYS_process_vm_readv 310 end
macro SYS_process_vm_writev 311 end const SYS_process_vm_writev 311 end
macro SYS_kcmp 312 end const SYS_kcmp 312 end
macro SYS_finit_module 313 end const SYS_finit_module 313 end

View File

@ -5,7 +5,7 @@
// @arg str_len: Int // @arg str_len: Int
// @arg str_ptr: Ptr // @arg str_ptr: Ptr
// @ret NULL/NEVER // @ret NULL/NEVER
macro assert fn assert with bool int ptr returns null do
rot rot
if else if else
"Assert failed: \"" eputs eputs "Assert failed: \"" eputs eputs

View File

@ -7,6 +7,8 @@ use super::commands::linux_x86_64_run;
pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
let debug = args.optimisation == "D";
let mut of_c = PathBuf::from(&args.out_file); let mut of_c = PathBuf::from(&args.out_file);
let (mut of_o, mut of_a) = if args.out_file == *crate::DEFAULT_OUT_FILE { let (mut of_o, mut of_a) = if args.out_file == *crate::DEFAULT_OUT_FILE {
let of_o = PathBuf::from("/tmp/mclang_comp.o"); let of_o = PathBuf::from("/tmp/mclang_comp.o");
@ -27,6 +29,7 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
let file = fs::File::create(&of_a)?; let file = fs::File::create(&of_a)?;
let mut writer = BufWriter::new(&file); let mut writer = BufWriter::new(&file);
let mut memories: Vec<(usize, usize)> = Vec::new(); let mut memories: Vec<(usize, usize)> = Vec::new();
let mut constants: Vec<(String, Option<usize>, Option<String>)> = Vec::new();
// println!("{}", tokens.len()); // println!("{}", tokens.len());
let mut strings: Vec<String> = Vec::new(); let mut strings: Vec<String> = Vec::new();
@ -68,7 +71,8 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
writeln!(writer, " ret")?; writeln!(writer, " ret")?;
writeln!(writer, "global _start")?; writeln!(writer, "global _start")?;
writeln!(writer, "_start:")?; writeln!(writer, "_start:")?;
writeln!(writer, " lea rbp, [rel ret_stack]")?;
writeln!(writer, " call func_main")?; writeln!(writer, " call func_main")?;
writeln!(writer, " jmp end")?; writeln!(writer, " jmp end")?;
@ -76,41 +80,73 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
let mut ti = 0; let mut ti = 0;
while ti < tokens.len() { while ti < tokens.len() {
let token = &tokens[ti]; let token = &tokens[ti];
println!("{:?}", token); // println!("{:?}", token);
writeln!(writer, "addr_{ti}:")?; if debug {
writeln!(writer, "addr_{ti}:")?;
if token.typ == OpType::Instruction(InstructionType::PushInt) {
writeln!(writer, " ;; -- {:?} {}", token.typ, token.value)?;
} else
if token.typ == OpType::Instruction(InstructionType::PushStr) {
writeln!(writer, " ;; -- {:?} {}", token.typ, strings[token.value].escape_debug())?;
} else {
writeln!(writer, " ;; -- {:?}", token.typ)?;
}
} else {
if ti != 0{
if &tokens[ti-1].typ == &OpType::Keyword(KeywordType::Else) ||
&tokens[ti-1].typ == &OpType::Keyword(KeywordType::End){
writeln!(writer, "addr_{ti}:")?;
}
}
if ti + 1 < tokens.len() && &tokens[ti+1].typ == &OpType::Keyword(KeywordType::End) {
writeln!(writer, "addr_{ti}:")?;
}
match &token.typ {
OpType::Keyword(keyword) => {
match keyword {
&KeywordType::End |
&KeywordType::While => {
writeln!(writer, "addr_{ti}:")?;
}
_ => ()
}
}
_ => ()
}
}
match token.typ.clone() { match token.typ.clone() {
// stack // stack
OpType::Instruction(instruction) => { OpType::Instruction(instruction) => {
match instruction { match instruction {
InstructionType::PushInt => { InstructionType::PushInt => {
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;
}, },
InstructionType::PushStr => { InstructionType::PushStr => {
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")?;
writeln!(writer, " push str_{}", strings.len())?; writeln!(writer, " mov rax, str_{}", strings.len())?;
writeln!(writer, " push rax")?;
strings.push(token.text.clone()); strings.push(token.text.clone());
ti += 1; ti += 1;
} }
InstructionType::Drop => { InstructionType::Drop => {
writeln!(writer, " ;; -- drop")?;
writeln!(writer, " pop rax")?; writeln!(writer, " pop rax")?;
ti += 1; ti += 1;
}, },
InstructionType::Print => { InstructionType::Print => {
writeln!(writer, " ;; -- print")?;
writeln!(writer, " pop rdi")?; writeln!(writer, " pop rdi")?;
writeln!(writer, " call print")?; writeln!(writer, " call print")?;
ti += 1; ti += 1;
}, },
InstructionType::Dup => { InstructionType::Dup => {
writeln!(writer, " ;; -- dup")?;
writeln!(writer, " pop rax")?; writeln!(writer, " pop rax")?;
writeln!(writer, " push rax")?; writeln!(writer, " push rax")?;
writeln!(writer, " push rax")?; writeln!(writer, " push rax")?;
@ -119,7 +155,6 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
}, },
InstructionType::Rot => { InstructionType::Rot => {
writeln!(writer, " ;; -- rot")?;
writeln!(writer, " pop rax")?; writeln!(writer, " pop rax")?;
writeln!(writer, " pop rbx")?; writeln!(writer, " pop rbx")?;
writeln!(writer, " pop rcx")?; writeln!(writer, " pop rcx")?;
@ -130,7 +165,6 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
ti += 1; ti += 1;
}, },
InstructionType::Swap => { InstructionType::Swap => {
writeln!(writer, " ;; -- swap")?;
writeln!(writer, " pop rax")?; writeln!(writer, " pop rax")?;
writeln!(writer, " pop rbx")?; writeln!(writer, " pop rbx")?;
writeln!(writer, " push rax")?; writeln!(writer, " push rax")?;
@ -139,7 +173,6 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
ti += 1; ti += 1;
}, },
InstructionType::Over => { InstructionType::Over => {
writeln!(writer, " ;; -- over")?;
writeln!(writer, " pop rax")?; writeln!(writer, " pop rax")?;
writeln!(writer, " pop rbx")?; writeln!(writer, " pop rbx")?;
writeln!(writer, " push rbx")?; writeln!(writer, " push rbx")?;
@ -148,15 +181,7 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
ti += 1; ti += 1;
}, },
//mem
InstructionType::Mem => {
writeln!(writer, " ;; -- mem")?;
writeln!(writer, " push mem")?;
ti += 1;
}
InstructionType::Load8 => { InstructionType::Load8 => {
writeln!(writer, " ;; -- load")?;
writeln!(writer, " pop rax")?; writeln!(writer, " pop rax")?;
writeln!(writer, " xor rbx, rbx")?; writeln!(writer, " xor rbx, rbx")?;
writeln!(writer, " mov bl, byte [rax]")?; writeln!(writer, " mov bl, byte [rax]")?;
@ -165,14 +190,12 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
} }
InstructionType::Store8 => { InstructionType::Store8 => {
writeln!(writer, " ;; -- store")?;
writeln!(writer, " pop rbx")?; writeln!(writer, " pop rbx")?;
writeln!(writer, " pop rax")?; writeln!(writer, " pop rax")?;
writeln!(writer, " mov byte [rax], bl")?; writeln!(writer, " mov byte [rax], bl")?;
ti += 1; ti += 1;
} }
InstructionType::Load32 => { InstructionType::Load32 => {
writeln!(writer, " ;; -- load")?;
writeln!(writer, " pop rax")?; writeln!(writer, " pop rax")?;
writeln!(writer, " xor rbx, rbx")?; writeln!(writer, " xor rbx, rbx")?;
writeln!(writer, " mov bl, dword [rax]")?; writeln!(writer, " mov bl, dword [rax]")?;
@ -181,14 +204,12 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
} }
InstructionType::Store32 => { InstructionType::Store32 => {
writeln!(writer, " ;; -- store")?;
writeln!(writer, " pop rbx")?; writeln!(writer, " pop rbx")?;
writeln!(writer, " pop rax")?; writeln!(writer, " pop rax")?;
writeln!(writer, " mov dword[rax], bl")?; writeln!(writer, " mov dword[rax], bl")?;
ti += 1; ti += 1;
} }
InstructionType::Load64 => { InstructionType::Load64 => {
writeln!(writer, " ;; -- load")?;
writeln!(writer, " pop rax")?; writeln!(writer, " pop rax")?;
writeln!(writer, " xor rbx, rbx")?; writeln!(writer, " xor rbx, rbx")?;
writeln!(writer, " mov bl, qword [rax]")?; writeln!(writer, " mov bl, qword [rax]")?;
@ -197,7 +218,6 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
} }
InstructionType::Store64 => { InstructionType::Store64 => {
writeln!(writer, " ;; -- store")?;
writeln!(writer, " pop rbx")?; writeln!(writer, " pop rbx")?;
writeln!(writer, " pop rax")?; writeln!(writer, " pop rax")?;
writeln!(writer, " mov qword [rax], bl")?; writeln!(writer, " mov qword [rax], bl")?;
@ -206,7 +226,6 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
// math // math
InstructionType::Plus => { InstructionType::Plus => {
writeln!(writer, " ;; -- plus")?;
writeln!(writer, " pop rax")?; writeln!(writer, " pop rax")?;
writeln!(writer, " pop rbx")?; writeln!(writer, " pop rbx")?;
writeln!(writer, " add rax, rbx")?; writeln!(writer, " add rax, rbx")?;
@ -214,7 +233,6 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
ti += 1; ti += 1;
}, },
InstructionType::Minus => { InstructionType::Minus => {
writeln!(writer, " ;; -- minus")?;
writeln!(writer, " pop rax")?; writeln!(writer, " pop rax")?;
writeln!(writer, " pop rbx")?; writeln!(writer, " pop rbx")?;
writeln!(writer, " sub rbx, rax")?; writeln!(writer, " sub rbx, rax")?;
@ -222,7 +240,6 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
ti += 1; ti += 1;
}, },
InstructionType::Equals => { InstructionType::Equals => {
writeln!(writer, " ;; -- equals")?;
writeln!(writer, " mov rcx, 0")?; writeln!(writer, " mov rcx, 0")?;
writeln!(writer, " mov rdx, 1")?; writeln!(writer, " mov rdx, 1")?;
writeln!(writer, " pop rax")?; writeln!(writer, " pop rax")?;
@ -233,7 +250,6 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
ti += 1; ti += 1;
}, },
InstructionType::Lt => { InstructionType::Lt => {
writeln!(writer, " ;; -- lt")?;
writeln!(writer, " mov rcx, 0")?; writeln!(writer, " mov rcx, 0")?;
writeln!(writer, " mov rdx, 1")?; writeln!(writer, " mov rdx, 1")?;
writeln!(writer, " pop rbx")?; writeln!(writer, " pop rbx")?;
@ -244,7 +260,6 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
ti += 1; ti += 1;
}, },
InstructionType::Gt => { InstructionType::Gt => {
writeln!(writer, " ;; -- gt")?;
writeln!(writer, " mov rcx, 0")?; writeln!(writer, " mov rcx, 0")?;
writeln!(writer, " mov rdx, 1")?; writeln!(writer, " mov rdx, 1")?;
writeln!(writer, " pop rbx")?; writeln!(writer, " pop rbx")?;
@ -255,7 +270,6 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
ti += 1; ti += 1;
}, },
InstructionType::NotEquals => { InstructionType::NotEquals => {
writeln!(writer, " ;; -- not equals")?;
writeln!(writer, " mov rcx, 1")?; writeln!(writer, " mov rcx, 1")?;
writeln!(writer, " mov rdx, 0")?; writeln!(writer, " mov rdx, 0")?;
writeln!(writer, " pop rax")?; writeln!(writer, " pop rax")?;
@ -266,7 +280,6 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
ti += 1; ti += 1;
}, },
InstructionType::Le => { InstructionType::Le => {
writeln!(writer, " ;; -- lt")?;
writeln!(writer, " mov rcx, 0")?; writeln!(writer, " mov rcx, 0")?;
writeln!(writer, " mov rdx, 1")?; writeln!(writer, " mov rdx, 1")?;
writeln!(writer, " pop rbx")?; writeln!(writer, " pop rbx")?;
@ -277,7 +290,6 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
ti += 1; ti += 1;
}, },
InstructionType::Ge => { InstructionType::Ge => {
writeln!(writer, " ;; -- gt")?;
writeln!(writer, " mov rcx, 0")?; writeln!(writer, " mov rcx, 0")?;
writeln!(writer, " mov rdx, 1")?; writeln!(writer, " mov rdx, 1")?;
writeln!(writer, " pop rbx")?; writeln!(writer, " pop rbx")?;
@ -288,7 +300,6 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
ti += 1; ti += 1;
}, },
InstructionType::Band => { InstructionType::Band => {
writeln!(writer, " ;; -- band")?;
writeln!(writer, " pop rax")?; writeln!(writer, " pop rax")?;
writeln!(writer, " pop rbx")?; writeln!(writer, " pop rbx")?;
writeln!(writer, " and rbx, rax")?; writeln!(writer, " and rbx, rax")?;
@ -296,7 +307,6 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
ti += 1; ti += 1;
}, },
InstructionType::Bor => { InstructionType::Bor => {
writeln!(writer, " ;; -- bor")?;
writeln!(writer, " pop rax")?; writeln!(writer, " pop rax")?;
writeln!(writer, " pop rbx")?; writeln!(writer, " pop rbx")?;
writeln!(writer, " or rbx, rax")?; writeln!(writer, " or rbx, rax")?;
@ -304,7 +314,6 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
ti += 1; ti += 1;
}, },
InstructionType::Shr => { InstructionType::Shr => {
writeln!(writer, " ;; -- shr")?;
writeln!(writer, " pop rcx")?; writeln!(writer, " pop rcx")?;
writeln!(writer, " pop rbx")?; writeln!(writer, " pop rbx")?;
writeln!(writer, " shr rbx, cl")?; writeln!(writer, " shr rbx, cl")?;
@ -312,7 +321,6 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
ti += 1; ti += 1;
}, },
InstructionType::Shl => { InstructionType::Shl => {
writeln!(writer, " ;; -- shl")?;
writeln!(writer, " pop rcx")?; writeln!(writer, " pop rcx")?;
writeln!(writer, " pop rbx")?; writeln!(writer, " pop rbx")?;
writeln!(writer, " shl rbx, cl")?; writeln!(writer, " shl rbx, cl")?;
@ -320,7 +328,6 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
ti += 1; ti += 1;
}, },
InstructionType::DivMod => { InstructionType::DivMod => {
writeln!(writer, " ;; -- div")?;
writeln!(writer, " xor rdx, rdx")?; writeln!(writer, " xor rdx, rdx")?;
writeln!(writer, " pop rbx")?; writeln!(writer, " pop rbx")?;
writeln!(writer, " pop rax")?; writeln!(writer, " pop rax")?;
@ -330,7 +337,6 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
ti += 1; ti += 1;
}, },
InstructionType::Mul => { InstructionType::Mul => {
writeln!(writer, " ;; -- mul")?;
writeln!(writer, " pop rax")?; writeln!(writer, " pop rax")?;
writeln!(writer, " pop rbx")?; writeln!(writer, " pop rbx")?;
writeln!(writer, " mul rbx")?; writeln!(writer, " mul rbx")?;
@ -338,14 +344,12 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
ti += 1; ti += 1;
}, },
InstructionType::Syscall0 => { InstructionType::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;
}, },
InstructionType::Syscall1 => { InstructionType::Syscall1 => {
writeln!(writer, " ;; -- syscall1")?;
writeln!(writer, " pop rax")?; writeln!(writer, " pop rax")?;
writeln!(writer, " pop rdi")?; writeln!(writer, " pop rdi")?;
writeln!(writer, " syscall")?; writeln!(writer, " syscall")?;
@ -353,7 +357,6 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
ti += 1; ti += 1;
}, },
InstructionType::Syscall2 => { InstructionType::Syscall2 => {
writeln!(writer, " ;; -- syscall2")?;
writeln!(writer, " pop rax")?; writeln!(writer, " pop rax")?;
writeln!(writer, " pop rdi")?; writeln!(writer, " pop rdi")?;
writeln!(writer, " pop rsi")?; writeln!(writer, " pop rsi")?;
@ -362,7 +365,6 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
ti += 1; ti += 1;
}, },
InstructionType::Syscall3 => { InstructionType::Syscall3 => {
writeln!(writer, " ;; -- syscall3")?;
writeln!(writer, " pop rax")?; writeln!(writer, " pop rax")?;
writeln!(writer, " pop rdi")?; writeln!(writer, " pop rdi")?;
writeln!(writer, " pop rsi")?; writeln!(writer, " pop rsi")?;
@ -373,7 +375,6 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
ti += 1; ti += 1;
}, },
InstructionType::Syscall4 => { InstructionType::Syscall4 => {
writeln!(writer, " ;; -- syscall4")?;
writeln!(writer, " pop rax")?; writeln!(writer, " pop rax")?;
writeln!(writer, " pop rdi")?; writeln!(writer, " pop rdi")?;
writeln!(writer, " pop rsi")?; writeln!(writer, " pop rsi")?;
@ -384,7 +385,6 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
ti += 1; ti += 1;
}, },
InstructionType::Syscall5 => { InstructionType::Syscall5 => {
writeln!(writer, " ;; -- syscall5")?;
writeln!(writer, " pop rax")?; writeln!(writer, " pop rax")?;
writeln!(writer, " pop rdi")?; writeln!(writer, " pop rdi")?;
writeln!(writer, " pop rsi")?; writeln!(writer, " pop rsi")?;
@ -396,7 +396,6 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
ti += 1; ti += 1;
}, },
InstructionType::Syscall6 => { InstructionType::Syscall6 => {
writeln!(writer, " ;; -- syscall6")?;
writeln!(writer, " pop rax")?; writeln!(writer, " pop rax")?;
writeln!(writer, " pop rdi")?; writeln!(writer, " pop rdi")?;
writeln!(writer, " pop rsi")?; writeln!(writer, " pop rsi")?;
@ -409,24 +408,65 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
ti += 1; ti += 1;
}, },
InstructionType::MemUse => { InstructionType::MemUse => {
writeln!(writer, " ;; -- MemUse")?;
writeln!(writer, " push mem_{}", token.addr.unwrap())?; writeln!(writer, " push mem_{}", token.addr.unwrap())?;
ti += 1; ti += 1;
}, },
InstructionType::None => unreachable!(), InstructionType::None => {
InstructionType::CastBool => ti += 1, println!("{:?}", token);
InstructionType::CastPtr => ti += 1, unreachable!()
InstructionType::CastInt => ti += 1, },
InstructionType::FnCall => { InstructionType::FnCall => {
writeln!(writer, " ;; -- FnCall")?;
writeln!(writer, " call func_{}", token.text)?; writeln!(writer, " call func_{}", token.text)?;
ti += 1; ti += 1;
}, },
InstructionType::Return => { InstructionType::Return => {
writeln!(writer, " ;; -- Return")?; writeln!(writer, " sub rbp, 8")?;
writeln!(writer, " mov rbx, qword [rbp]")?;
writeln!(writer, " push rbx")?;
writeln!(writer, " ret")?; writeln!(writer, " ret")?;
ti += 1; ti += 1;
}, },
InstructionType::CastBool => {
ti += 1;
}
InstructionType::CastPtr => {
ti += 1;
}
InstructionType::CastInt => {
ti += 1;
}
InstructionType::CastVoid => {
ti += 1;
}
InstructionType::TypeBool => {
ti += 1;
}
InstructionType::TypePtr => {
ti += 1;
}
InstructionType::TypeInt => {
ti += 1;
}
InstructionType::TypeVoid => {
ti += 1;
}
InstructionType::TypeStr => {
ti += 1;
}
InstructionType::TypeAny => {
ti += 1;
}
InstructionType::Returns => {
ti += 1;
}
InstructionType::With => {
ti += 1;
}
InstructionType::ConstUse => {
writeln!(writer, " mov rax, qword [const_{}]", token.text)?;
writeln!(writer, " push rax")?;
ti += 1;
},
} }
} }
@ -436,32 +476,27 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
// block // block
KeywordType::If => { KeywordType::If => {
writeln!(writer, " ;; -- if")?;
writeln!(writer, " pop rax")?; writeln!(writer, " pop rax")?;
writeln!(writer, " test rax, rax")?; writeln!(writer, " test rax, rax")?;
writeln!(writer, " jz addr_{}", token.jmp)?; writeln!(writer, " jz addr_{}", token.jmp)?;
ti += 1; ti += 1;
}, },
KeywordType::Else => { KeywordType::Else => {
writeln!(writer, " ;; -- else")?;
writeln!(writer, " jmp addr_{}", token.jmp)?; writeln!(writer, " jmp addr_{}", token.jmp)?;
ti += 1; ti += 1;
}, },
KeywordType::While => { KeywordType::While => {
writeln!(writer, " ;; -- while")?;
ti += 1; ti += 1;
} }
KeywordType::Do => { KeywordType::Do => {
writeln!(writer, " ;; -- do")?;
writeln!(writer, " pop rax")?; writeln!(writer, " pop rax")?;
writeln!(writer, " test rax, rax")?; writeln!(writer, " test rax, rax")?;
writeln!(writer, " jz addr_{}", token.jmp)?; writeln!(writer, " jz addr_{}", token.jmp)?;
ti += 1; ti += 1;
} }
KeywordType::End => { KeywordType::End => {
writeln!(writer, " ;; -- end")?;
if ti + 1 != token.jmp { if ti + 1 != token.jmp {
writeln!(writer, " jmp addr_{}", token.jmp)?; // writeln!(writer, " jmp addr_{}", token.jmp)?;
} }
ti += 1; ti += 1;
}, },
@ -470,11 +505,19 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
ti += 1; ti += 1;
} }
KeywordType::Include => unreachable!(), KeywordType::Include => unreachable!(),
KeywordType::Constant => todo!(), KeywordType::Constant => {
KeywordType::Function => { // TODO: after we add c style strings add supoort for them in constants
writeln!(writer, "func_{}:", token.text)?; constants.push((token.text.clone(), Some(token.value), None));
ti += 1; ti += 1;
}, },
KeywordType::Function => {
writeln!(writer, "func_{}:", token.text)?;
writeln!(writer, " pop rbx")?;
writeln!(writer, " mov qword [rbp], rbx")?;
writeln!(writer, " add rbp, 8")?;
ti += 1;
},
KeywordType::FunctionDo => ti += 1,
} }
} }
} }
@ -491,11 +534,27 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
writeln!(writer, " str_{}: db {} ; {}", i, s_list, s.escape_default())?; writeln!(writer, " str_{}: db {} ; {}", i, s_list, s.escape_default())?;
} }
for (_, s) in constants.iter().enumerate() {
if let Some(v) = &s.1 {
writeln!(writer, " const_{}: dq {}", s.0, v)?;
} else if let Some(_v) = &s.2 {
todo!();
} else {
unreachable!();
}
}
writeln!(writer, "segment .bss")?; writeln!(writer, "segment .bss")?;
for (_, s) in memories.iter().enumerate() { for (_, s) in memories.iter().enumerate() {
writeln!(writer, " mem_{}: resb {}", s.0, s.1)?; writeln!(writer, " mem_{}: resb {}", s.0, s.1)?;
} }
writeln!(writer, " mem: resb {}", crate::compile::MEM_SZ)?; writeln!(writer, " ret_stack: resq 256")?;
// for t in tokens {
// println!("{t:?}");
// }
writer.flush()?; writer.flush()?;
linux_x86_64_compile_and_link(&of_a, &of_o, &of_c, args.quiet)?; linux_x86_64_compile_and_link(&of_a, &of_o, &of_c, args.quiet)?;
@ -504,5 +563,6 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
return Ok(c); return Ok(c);
} }
Ok(0) Ok(0)
} }

View File

@ -1,5 +1,4 @@
pub const ALLOW_MACRO_REDEFINITION: bool = true;
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
@ -33,7 +32,6 @@ pub enum InstructionType {
// mem // mem
Mem,
Load8, Load8,
Store8, Store8,
Load32, Load32,
@ -53,10 +51,23 @@ pub enum InstructionType {
CastBool, CastBool,
CastPtr, CastPtr,
CastInt, CastInt,
CastVoid,
// typing
TypeBool,
TypePtr,
TypeInt,
TypeVoid,
TypeStr,
TypeAny,
Returns,
With,
FnCall, FnCall,
Return,
MemUse, MemUse,
ConstUse,
Return,
None // Used for macros and any other non built in word definitions None // Used for macros and any other non built in word definitions
} }
@ -70,7 +81,8 @@ pub enum KeywordType {
Include, Include,
Memory, Memory,
Constant, Constant,
Function Function,
FunctionDo
} }
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
@ -137,7 +149,6 @@ impl OpType {
InstructionType::Shl => "shl", InstructionType::Shl => "shl",
InstructionType::DivMod => "divmod", InstructionType::DivMod => "divmod",
InstructionType::Mul => "*", InstructionType::Mul => "*",
InstructionType::Mem => "mem",
InstructionType::Load8 => "load8", InstructionType::Load8 => "load8",
InstructionType::Store8 => "store8", InstructionType::Store8 => "store8",
InstructionType::Load32 => "load32", InstructionType::Load32 => "load32",
@ -154,10 +165,20 @@ impl OpType {
InstructionType::CastBool => "cast(bool", InstructionType::CastBool => "cast(bool",
InstructionType::CastPtr => "cast(ptr)", InstructionType::CastPtr => "cast(ptr)",
InstructionType::CastInt => "cast(int)", InstructionType::CastInt => "cast(int)",
InstructionType::MemUse => "MemUse", InstructionType::CastVoid => "cast(void)",
InstructionType::None => "None", InstructionType::None => "None",
InstructionType::FnCall => "Function Call", InstructionType::MemUse => "Memory use (internal)",
InstructionType::FnCall => "Function Call (Internal)",
InstructionType::ConstUse => "Constant Use (Internal)",
InstructionType::Return => "return", InstructionType::Return => "return",
InstructionType::TypeBool => "bool",
InstructionType::TypePtr => "ptr",
InstructionType::TypeInt => "int",
InstructionType::TypeVoid => "void",
InstructionType::TypeStr => "str",
InstructionType::Returns => "returns",
InstructionType::With => "with",
InstructionType::TypeAny => "any",
} }
} }
OpType::Keyword(keyword) => { OpType::Keyword(keyword) => {
@ -171,6 +192,7 @@ impl OpType {
KeywordType::Memory => "memory", KeywordType::Memory => "memory",
KeywordType::Function => "fn", KeywordType::Function => "fn",
KeywordType::Constant => "const", KeywordType::Constant => "const",
KeywordType::FunctionDo => "do",
} }
} }
@ -226,6 +248,8 @@ pub enum Types {
Bool, Bool,
Ptr, Ptr,
Int, Int,
Void,
Str,
Any Any
// U8, // U8,
// U16, // U16,

View File

@ -96,12 +96,6 @@ pub fn run(tokens: &[crate::constants::Operator]) -> Result<i32>{
// let _ = io::stdout().flush(); // let _ = io::stdout().flush();
ti += 1; ti += 1;
}, },
// mem
InstructionType::Mem => {
stack.push(0);
ti += 1;
}
InstructionType::Load8 | InstructionType::Load8 |
InstructionType::Load32 | InstructionType::Load32 |
InstructionType::Load64 => { InstructionType::Load64 => {
@ -294,12 +288,22 @@ pub fn run(tokens: &[crate::constants::Operator]) -> Result<i32>{
stack.push(*m); stack.push(*m);
ti += 1; ti += 1;
}, },
InstructionType::CastBool => ti += 1, InstructionType::CastBool |
InstructionType::CastPtr => ti += 1, InstructionType::CastPtr |
InstructionType::CastInt => ti += 1, InstructionType::CastInt |
InstructionType::FnCall |
InstructionType::Return |
InstructionType::CastVoid |
InstructionType::TypeBool |
InstructionType::TypePtr |
InstructionType::TypeInt |
InstructionType::TypeVoid |
InstructionType::TypeStr |
InstructionType::TypeAny |
InstructionType::Returns |
InstructionType::With => ti += 1,
InstructionType::None => unreachable!(), InstructionType::None => unreachable!(),
InstructionType::FnCall => todo!(), InstructionType::ConstUse => todo!(),
InstructionType::Return => todo!(),
} }
} }
@ -336,6 +340,7 @@ pub fn run(tokens: &[crate::constants::Operator]) -> Result<i32>{
KeywordType::Include => unreachable!(), KeywordType::Include => unreachable!(),
KeywordType::Constant => todo!(), KeywordType::Constant => todo!(),
KeywordType::Function => todo!(), KeywordType::Function => todo!(),
KeywordType::FunctionDo => todo!(),
} }
} }

View File

@ -1,5 +1,5 @@
use crate::{constants::{Token, TokenType}, preprocessor::preprocess, Args}; use crate::{constants::{Token, TokenType}, Args};
use color_eyre::Result; use color_eyre::Result;
fn lex_word(s: String, tok_type: TokenType) -> (TokenType, String) { fn lex_word(s: String, tok_type: TokenType) -> (TokenType, String) {
@ -89,7 +89,7 @@ fn lex_line(text: &str) -> Vec<(usize, String, TokenType)> {
tokens tokens
} }
pub fn lex<S: Into<String> + std::marker::Copy>(code: &str, file: S, args: &Args) -> Result<Vec<Token>> { pub fn lex<S: Into<String> + std::marker::Copy>(code: &str, file: S, _args: &Args) -> Result<Vec<Token>> {
let lines: Vec<(usize, &str)> = code let lines: Vec<(usize, &str)> = code
.split(['\n', '\r']) .split(['\n', '\r'])
.enumerate() .enumerate()

View File

@ -53,8 +53,12 @@ pub struct Args {
/// Unsafe mode, disables typechecking /// Unsafe mode, disables typechecking
#[arg(long="unsafe", default_value_t = false)] #[arg(long="unsafe", default_value_t = false)]
unsaf: bool unsaf: bool,
/// Optimisation level, available levels: 'D': debug, '0': No optimisations
#[arg(long, short='O', default_value_t=String::from("0"))]
optimisation: String,
//#[arg(long, short='F')] //#[arg(long, short='F')]
//features: Vec<String>, //features: Vec<String>,
@ -82,7 +86,7 @@ fn main() {
return; return;
}; };
let Ok(tokens) = typechecker::typecheck(&tokens, &args) else { let Ok(tokens) = typechecker::typecheck(tokens, &args) else {
error!("Typechecking failed, exiting!"); error!("Typechecking failed, exiting!");
return; return;
}; };

View File

@ -1,11 +1,12 @@
use std::ops::Deref; use std::ops::Deref;
use crate::{constants::{Operator, OpType, Token, TokenType, Loc, KeywordType, InstructionType}, lerror, preprocessor::preprocess, Args}; use crate::{constants::{Operator, OpType, Token, TokenType, Loc, KeywordType, InstructionType}, lerror, preprocessor::Preprocessor, Args};
use color_eyre::Result; use color_eyre::Result;
use eyre::eyre; use eyre::eyre;
pub fn cross_ref(mut program: Vec<Operator>) -> Result<Vec<Operator>> { pub fn cross_ref(mut program: Vec<Operator>) -> Result<Vec<Operator>> {
let mut stack: Vec<usize> = Vec::new(); let mut stack: Vec<usize> = Vec::new();
for ip in 0..program.len() { for ip in 0..program.len() {
let op = &program.clone()[ip]; let op = &program.clone()[ip];
match op.typ { match op.typ {
@ -15,9 +16,12 @@ pub fn cross_ref(mut program: Vec<Operator>) -> Result<Vec<Operator>> {
stack.push(ip); stack.push(ip);
} }
OpType::Keyword(KeywordType::Else) => { OpType::Keyword(KeywordType::Else) => {
let if_ip = stack.pop().unwrap(); let if_ip = if let Some(x) = stack.pop() { x } else {
lerror!(&op.loc, "Unclosed-if else block");
return Err(eyre!("Cross referencing"));
};
if program[if_ip].typ != OpType::Keyword(KeywordType::If) { if program[if_ip].typ != OpType::Keyword(KeywordType::If) {
lerror!(&op.clone().loc,"'end' can only close 'if' blocks"); lerror!(&op.clone().loc,"'else' can only close 'if' blocks");
return Err(eyre!("Bad block")); return Err(eyre!("Bad block"));
} }
@ -25,36 +29,48 @@ pub fn cross_ref(mut program: Vec<Operator>) -> Result<Vec<Operator>> {
stack.push(ip); stack.push(ip);
}, },
OpType::Keyword(KeywordType::End) => { OpType::Keyword(KeywordType::End) => {
let block_ip = stack.pop().unwrap(); let block_ip = if let Some(block_ip) = stack.pop() { block_ip } else {
lerror!(&op.loc, "Unclosed if, if-else, while-do, function, memory, or constant");
return Err(eyre!("Cross referencing"));
};
match &program[block_ip].typ {
OpType::Keyword(KeywordType::If) |
OpType::Keyword(KeywordType::Else) => {
program[block_ip].jmp = ip;
program[ip].jmp = ip + 1;
}
if program[block_ip].typ == OpType::Keyword(KeywordType::If) || OpType::Keyword(KeywordType::Do) => {
program[block_ip].typ == OpType::Keyword(KeywordType::Else) { program[ip].jmp = program[block_ip].jmp;
program[block_ip].jmp = ip + 1;
program[block_ip].jmp = ip; }
program[ip].jmp = ip + 1; OpType::Keyword(KeywordType::FunctionDo) => {
program[ip].typ = OpType::Instruction(InstructionType::Return);
}
OpType::Keyword(KeywordType::Memory) |
OpType::Keyword(KeywordType::Function) |
OpType::Keyword(KeywordType::Constant) => (),
} else if program[block_ip].typ == OpType::Keyword(KeywordType::Do) { a => {
program[ip].jmp = program[block_ip].jmp; println!("{a:?}");
program[block_ip].jmp = ip + 1; lerror!(&op.clone().loc,"'end' can only close if, if-else, while-do, function, memory, or constant blocks");
} else if program[block_ip].typ == OpType::Keyword(KeywordType::Function) { return Err(eyre!(""));
program[ip].typ = OpType::Instruction(InstructionType::Return); }
program[block_ip].typ = OpType::Keyword(KeywordType::Do);
} else {
lerror!(&op.clone().loc,"'end' can only close 'if' blocks");
return Err(eyre!(""));
} }
} }
OpType::Keyword(KeywordType::Do) => { OpType::Keyword(KeywordType::Do) => {
let block_ip = stack.pop().unwrap(); let block_ip = if let Some(x) = stack.pop() { x } else {
lerror!(&op.loc, "Unclosed while-do block");
return Err(eyre!("Cross referencing"));
};
if program[block_ip].typ == OpType::Keyword(KeywordType::Function) { if program[block_ip].typ == OpType::Keyword(KeywordType::Function) {
program[ip].typ = OpType::Keyword(KeywordType::Function); program[ip].typ = OpType::Keyword(KeywordType::FunctionDo);
} }
program[ip].jmp = block_ip; program[ip].jmp = block_ip;
// println!("{}", block_ip);
stack.push(ip); stack.push(ip);
} }
_ => () _ => ()
@ -63,7 +79,7 @@ pub fn cross_ref(mut program: Vec<Operator>) -> Result<Vec<Operator>> {
} }
if !stack.is_empty() { if !stack.is_empty() {
println!("{:?}", stack); println!("{:?}", stack);
lerror!(&program[stack.pop().expect("Empy stack")].clone().loc,"Unclosed block"); lerror!(&program[stack.pop().expect("Empy stack")].clone().loc,"Unclosed block, {:?}", program[stack.pop().expect("Empy stack")].clone());
return Err(eyre!("Unclosed block")); return Err(eyre!("Unclosed block"));
} }
@ -116,14 +132,13 @@ impl Parser {
} }
}; };
//"print" => tokens.push(Operator::new(OpType::Print, 0, token.file.clone(), token.line, token.col)),
} }
let t = Preprocessor::new(tokens.clone(), args).preprocess()?.get_ops();
tokens = cross_ref(tokens.clone())?; let t = cross_ref(t.clone())?;
let t = preprocess(tokens, args)?;
Ok(t.0) Ok(t)
} }
} }
@ -161,7 +176,6 @@ pub fn lookup_word<P: Deref<Target = Loc>>(s: &str, _pos: P) -> OpType {
// mem // mem
"mem" => OpType::Instruction(InstructionType::Mem),
"load8" => OpType::Instruction(InstructionType::Load8), "load8" => OpType::Instruction(InstructionType::Load8),
"store8" => OpType::Instruction(InstructionType::Store8), "store8" => OpType::Instruction(InstructionType::Store8),
"load32" => OpType::Instruction(InstructionType::Load32), "load32" => OpType::Instruction(InstructionType::Load32),
@ -176,9 +190,10 @@ 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(bool)" => OpType::Instruction(InstructionType::CastBool),
"cast(ptr)" => OpType::Instruction(InstructionType::CastPtr), "cast(ptr)" => OpType::Instruction(InstructionType::CastPtr),
"cast(int)" => OpType::Instruction(InstructionType::CastInt), "cast(int)" => OpType::Instruction(InstructionType::CastInt),
"cast(void)" => OpType::Instruction(InstructionType::CastVoid),
// block // block
"if" => OpType::Keyword(KeywordType::If), "if" => OpType::Keyword(KeywordType::If),
"else" => OpType::Keyword(KeywordType::Else), "else" => OpType::Keyword(KeywordType::Else),
@ -189,6 +204,15 @@ pub fn lookup_word<P: Deref<Target = Loc>>(s: &str, _pos: P) -> OpType {
"memory" => OpType::Keyword(KeywordType::Memory), "memory" => OpType::Keyword(KeywordType::Memory),
"const" => OpType::Keyword(KeywordType::Constant), "const" => OpType::Keyword(KeywordType::Constant),
"fn" => OpType::Keyword(KeywordType::Function), "fn" => OpType::Keyword(KeywordType::Function),
"return" => OpType::Instruction(InstructionType::Return),
"returns" => OpType::Instruction(InstructionType::Returns),
"bool" => OpType::Instruction(InstructionType::TypeBool),
"int" => OpType::Instruction(InstructionType::TypeInt),
"ptr" => OpType::Instruction(InstructionType::TypePtr),
"void" => OpType::Instruction(InstructionType::TypeVoid),
"any" => OpType::Instruction(InstructionType::TypeAny),
"str" => OpType::Instruction(InstructionType::TypeStr),
"with" => OpType::Instruction(InstructionType::With),
_ => OpType::Instruction(InstructionType::None) _ => OpType::Instruction(InstructionType::None)
} }

View File

@ -2,7 +2,7 @@
use color_eyre::Result; use color_eyre::Result;
use eyre::eyre; use eyre::eyre;
use crate::{constants::{Token, OpType, InstructionType, Loc, Operator}, parser::lookup_word, lerror}; use crate::{constants::{ OpType, InstructionType, Loc, Operator}, lerror};
fn stack_pop(stack: &mut Vec<usize>, loc: &Loc) -> Result<usize> { fn stack_pop(stack: &mut Vec<usize>, loc: &Loc) -> Result<usize> {
if let Some(i) = stack.pop() { Ok(i) } else { if let Some(i) = stack.pop() { Ok(i) } else {
@ -14,19 +14,13 @@ fn stack_pop(stack: &mut Vec<usize>, loc: &Loc) -> Result<usize> {
pub fn precompile(tokens: &Vec<Operator>) -> Result<Vec<usize>>{ pub fn precompile(tokens: &Vec<Operator>) -> Result<Vec<usize>>{
let mut stack: Vec<usize> = Vec::new(); let mut stack: Vec<usize> = Vec::new();
for token in tokens.iter() { for token in tokens.iter() {
match token.typ.clone() { match token.typ.clone() {
OpType::Instruction(i) => { OpType::Instruction(i) => {
let loc = token.loc.clone(); let loc = token.loc.clone();
match i { match i {
InstructionType::PushInt => { InstructionType::PushInt => {
if let Ok(i) = token.text.parse::<usize>() { stack.push(token.value);
stack.push(i);
} else {
lerror!(&token.loc, "Bad number");
return Err(eyre!(""));
}
}, },
InstructionType::Plus => { InstructionType::Plus => {
let a = stack_pop(&mut stack, &loc)?; let a = stack_pop(&mut stack, &loc)?;

View File

@ -1,251 +1,364 @@
use std::collections::HashMap; use std::collections::HashMap;
use std::ops::Deref;
use std::path::{PathBuf, Path}; use std::path::{PathBuf, Path};
use color_eyre::Result; use color_eyre::Result;
use eyre::eyre; use eyre::eyre;
use crate::constants::{Token, Loc, OpType, TokenType, KeywordType, InstructionType, Operator}; use crate::constants::{Loc, OpType, TokenType, KeywordType, InstructionType, Operator};
use crate::lexer::lex; use crate::lexer::lex;
use crate::precompiler::precompile; use crate::precompiler::precompile;
use crate::{lerror, lnote, Args, warn, linfo, parser}; use crate::{lerror, Args, warn, linfo, parser};
use crate::parser::lookup_word; use crate::parser::lookup_word;
#[derive(Debug)] #[derive(Debug)]
pub struct Function { pub struct Function {
pub loc: Loc, pub loc: Loc,
pub name: String pub name: String
} }
type Functions = HashMap<String, Function>; #[derive(Debug)]
type Memories = HashMap<String, usize>; pub struct Constant {
pub loc: Loc,
pub fn preprocess(tokens: Vec<Operator>, args: &Args) -> Result<(Vec<Operator>, Functions)>{ pub name: String
let mut program: Vec<Operator> = Vec::new();
let mut functions: Functions = HashMap::new();
let mut memories: Memories = HashMap::new();
let mut rtokens = tokens;
rtokens.reverse();
while !rtokens.is_empty() {
let mut token = rtokens.pop().unwrap();
let op_type = token.typ.clone();
match token.clone() {
_ 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!(""));
}
let include_path = rtokens.pop().unwrap();
if include_path.tok_typ != TokenType::String {
lerror!(&include_path.loc, "Bad include path, expected {} but found {}", TokenType::String.human(), include_path.typ.human());
return Err(eyre!(""));
}
let mut in_paths = args.include.clone();
in_paths.append(&mut crate::DEFAULT_INCLUDES.to_vec().clone().iter().map(|f| (*f).to_string()).collect::<Vec<String>>());
let mut include_code = String::new();
if include_path.text.chars().collect::<Vec<char>>()[0] == '.' {
let p = Path::new(include_path.loc.0.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 {
let p = PathBuf::from(path);
let p = p.join(&include_path.text);
if p.exists() {
include_code = std::fs::read_to_string(p)?;
}
}
}
if include_code.is_empty() {
lerror!(&include_path.loc, "Include file in path '{}' was not found or is empty", include_path.text);
return Err(eyre!(""));
}
let code = lex(&include_code, &args.in_file, &args)?;
let mut p = parser::Parser::new(code);
let mut code = p.parse(args)?;
code.reverse();
rtokens.append(&mut code);
}
_ if op_type == OpType::Keyword(KeywordType::Memory) => {
if rtokens.is_empty() {
lerror!(&token.loc, "Memory name not found, expected {} but found nothing", TokenType::String.human());
return Err(eyre!(""));
}
let memory_name = rtokens.pop().unwrap();
if memory_name.tok_typ != TokenType::Word {
lerror!(&memory_name.loc, "Bad memory name, expected {} but found {}", TokenType::Word.human(), memory_name.typ.human());
return Err(eyre!(""));
}
if functions.get(&memory_name.text).is_some() {
lerror!(&memory_name.loc, "Memory name cannot replace function name, got {}", memory_name.text);
let m = functions.get(&memory_name.text).unwrap();
linfo!(&m.loc, "Function found here");
return Err(eyre!(""));
}
let mut code: Vec<Operator> = Vec::new();
let mut depth = 0;
while !rtokens.is_empty() {
let t = rtokens.pop().unwrap();
let typ = t.typ.clone();
if typ == OpType::Keyword(KeywordType::End) && depth == 0 {
break;
} else if typ == OpType::Keyword(KeywordType::End) && depth != 0 {
depth -= 1;
code.push(t);
} else if typ == OpType::Keyword(KeywordType::If) || typ == OpType::Keyword(KeywordType::Do) {
code.push(t);
depth += 1;
} else {
code.push(t);
}
}
let res = precompile(&code)?;
if res.len() != 1 {
lerror!(&token.loc, "Expected 1 number, got {:?}", res);
return Err(eyre!(""));
}
token.value = res[0];
token.addr = Some(memories.len());
program.push(token);
memories.insert(memory_name.text, memories.len());
}
_ if op_type == OpType::Keyword(KeywordType::Function) => {
if rtokens.is_empty() {
lerror!(&token.loc, "Function name not found, expected {} but found nothing", TokenType::Word.human());
return Err(eyre!(""));
}
let function_name = rtokens.pop().unwrap();
if function_name.tok_typ != TokenType::Word {
lerror!(&function_name.loc, "Bad Function name, expected {} but found {}", TokenType::Word.human(), function_name.typ.human());
return Err(eyre!(""));
}
if memories.get(&function_name.text).is_some() {
lerror!(&function_name.loc, "Function name cannot replace memory name, got {}", function_name.text);
return Err(eyre!(""));
}
if functions.get(&function_name.text).is_some() {
lerror!(&function_name.loc, "Functions cannot be redefined, got {}", function_name.text);
return Err(eyre!(""));
}
functions.insert(function_name.text.clone(), Function{
loc: function_name.loc.clone(),
name: function_name.text.clone(),
});
token.text = function_name.text;
rtokens.pop();
program.push(token);
}
_ => {
if op_type == OpType::Keyword(KeywordType::Do) {
println!("{:?}", token);
}
program.push(token);
}
}
}
//* Feel free to fix this horrifying shit
//* i wanna kms
let mut times = 0;
while program.iter().map(|f| {
if f.tok_typ == TokenType::Word && f.typ != OpType::Instruction(InstructionType::FnCall) && f.typ != OpType::Instruction(InstructionType::MemUse){
lookup_word(&f.text, &f.loc)
} else {
OpType::Instruction(InstructionType::PushInt) // i hate myself, this is a randomly picked optype so its happy and works
}
}).collect::<Vec<OpType>>().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");
break
}
program = expand(program, &functions, &memories)?;
times += 1;
}
Ok((program, functions))
} }
pub fn expand(tokens: Vec<Operator>, funcs: &Functions, mems: &Memories) -> Result<Vec<Operator>> { #[derive(Debug)]
let mut program: Vec<Operator> = Vec::new(); pub struct Memory {
pub loc: Loc,
pub id: usize
}
let mut rtokens = tokens.clone(); type Functions = HashMap<String, Function>;
rtokens.reverse(); type Memories = HashMap<String, Memory>;
type Constants = HashMap<String, Constant>;
while !rtokens.is_empty() { pub struct Preprocessor<'a> {
let op = rtokens.pop().unwrap(); program: Vec<Operator>,
let op_type = op.typ.clone(); functions: Functions,
if op.tok_typ.clone() == TokenType::Word { memories: Memories,
match op_type { constants: Constants,
OpType::Instruction(InstructionType::None) => { args: &'a Args
let m = funcs.get(&op.text); }
let mem = mems.get(&op.text);
if let Some(m) = m {
let mut t = op.clone(); impl<'a> Preprocessor<'a> {
t.typ = OpType::Instruction(InstructionType::FnCall); pub fn new(prog: Vec<Operator>, args: &'a Args) -> Self {
t.text = m.name.clone(); Self {
program.push(t); program: prog,
} else args: args,
if let Some(mem) = mem { functions: HashMap::new(),
let mut t = op.clone(); memories: HashMap::new(),
t.addr = Some(*mem); constants: HashMap::new(),
t.typ = OpType::Instruction(InstructionType::MemUse);
program.push(t);
}
else {
lerror!(&op.loc, "expand: Unknown word '{}'", op.text.clone());
return Err(eyre!(""));
}
}
_ => {
program.push(op.clone());
}
}
} else {
program.push(op.clone());
} }
if op.typ == OpType::Keyword(KeywordType::Do) {
println!("expand: {:?}", op);
}
} }
pub fn preprocess(&mut self) -> Result<&mut Preprocessor<'a>>{
// println!("pre: has do tokens: {:?}", self.program.iter().map(|t| if t.typ == OpType::Keyword(KeywordType::Do) {Some(t)} else {None} ).collect::<Vec<Option<&Operator>>>());
let mut program: Vec<Operator> = Vec::new();
let mut rtokens = self.program.clone();
rtokens.reverse();
while !rtokens.is_empty() {
let mut token = rtokens.pop().unwrap();
// println!("{token:?}");
let op_type = token.typ.clone();
match token.clone() {
_ 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!(""));
}
let include_path = rtokens.pop().unwrap();
if include_path.tok_typ != TokenType::String {
lerror!(&include_path.loc, "Bad include path, expected {} but found {}", TokenType::String.human(), include_path.typ.human());
return Err(eyre!(""));
}
let mut in_paths = self.args.include.clone();
in_paths.append(&mut crate::DEFAULT_INCLUDES.to_vec().clone().iter().map(|f| (*f).to_string()).collect::<Vec<String>>());
let mut include_code = String::new();
if include_path.text.chars().collect::<Vec<char>>()[0] == '.' {
let p = Path::new(include_path.loc.0.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 {
let p = PathBuf::from(path);
let p = p.join(&include_path.text);
if p.exists() {
include_code = std::fs::read_to_string(p)?;
}
}
}
if include_code.is_empty() {
lerror!(&include_path.loc, "Include file in path '{}' was not found or is empty", include_path.text);
return Err(eyre!(""));
}
let code = lex(&include_code, &self.args.in_file, &self.args)?;
let mut p = parser::Parser::new(code);
let mut code = p.parse(self.args)?;
code.reverse();
rtokens.append(&mut code);
}
_ if op_type == OpType::Keyword(KeywordType::Memory) => {
if rtokens.is_empty() {
lerror!(&token.loc, "Memory name not found, expected {} but found nothing", TokenType::String.human());
return Err(eyre!(""));
}
Ok(program) let memory_name = rtokens.pop().unwrap();
self.is_word_available(&memory_name, KeywordType::Function)?;
let mut code: Vec<Operator> = Vec::new();
let mut depth = 0;
while !rtokens.is_empty() {
let t = rtokens.pop().unwrap();
let typ = t.typ.clone();
if typ == OpType::Keyword(KeywordType::End) && depth == 0 {
break;
} else if typ == OpType::Keyword(KeywordType::End) && depth != 0 {
depth -= 1;
code.push(t);
} else if typ == OpType::Keyword(KeywordType::If) || typ == OpType::Keyword(KeywordType::Do) {
code.push(t);
depth += 1;
} else {
code.push(t);
}
}
let res = precompile(&code)?;
if res.len() != 1 {
lerror!(&token.loc, "Expected 1 number, got {:?}", res);
return Err(eyre!(""));
}
token.value = res[0];
token.addr = Some(self.memories.len());
program.push(token.clone());
self.memories.insert(memory_name.text, Memory { loc: token.loc, id: self.memories.len() });
}
_ if op_type == OpType::Keyword(KeywordType::Function) => {
if rtokens.is_empty() {
lerror!(&token.loc, "Function name not found, expected {} but found nothing", TokenType::Word.human());
return Err(eyre!(""));
}
let function_name = rtokens.pop().unwrap();
self.is_word_available(&function_name, KeywordType::Function)?;
self.functions.insert(function_name.text.clone(), Function{
loc: function_name.loc.clone(),
name: function_name.text.clone(),
});
token.text = function_name.text;
// println!("{:?}", token);
program.push(token);
}
_ if op_type == OpType::Keyword(KeywordType::Constant) => {
if rtokens.is_empty() {
lerror!(&token.loc, "Constant name not found, expected {} but found nothing", TokenType::Word.human());
return Err(eyre!(""));
}
let const_name = rtokens.pop().unwrap();
self.is_word_available(&const_name, KeywordType::Function)?;
self.constants.insert(const_name.text.clone(), Constant{
loc: const_name.loc.clone(),
name: const_name.text.clone(),
});
token.text = const_name.text;
let item = rtokens.pop().unwrap();
if item.tok_typ == TokenType::Int {
token.value = item.value;
}
if let None = rtokens.pop() {
lerror!(&token.loc, "Constant was not closed with an 'end' instruction, expected 'end' but found nothing");
return Err(eyre!(""));
}
// token.value =
program.push(token);
}
_ => {
program.push(token);
}
}
}
self.program = program;
// println!("has do tokens: {:?}", self.program.iter().map(|t| if t.typ == OpType::Keyword(KeywordType::Do) {Some(t)} else {None} ).collect::<Vec<Option<&Operator>>>());
//* Feel free to fix this horrifying shit
//* i wanna kms
let mut times = 0;
// dbg!(program.clone());
while self.program.iter().map(|f| {
if f.tok_typ == TokenType::Word && f.typ != OpType::Instruction(InstructionType::FnCall) && f.typ != OpType::Instruction(InstructionType::MemUse) && f.typ != OpType::Keyword(KeywordType::Function) && f.typ != OpType::Keyword(KeywordType::Constant) && f.typ != OpType::Instruction(InstructionType::ConstUse) {
lookup_word(&f.text, &f.loc)
} else {
OpType::Instruction(InstructionType::PushInt) // i hate myself, this is a randomly picked optype so its happy and works
}
}).collect::<Vec<OpType>>().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");
break
}
self.expand()?;
times += 1;
}
Ok(self)
}
pub fn expand(&mut self) -> Result<()> {
let mut program: Vec<Operator> = Vec::new();
// println!("{:?}", self.functions);
let mut rtokens = self.program.clone();
rtokens.reverse();
while !rtokens.is_empty() {
let op = rtokens.pop().unwrap();
let op_type = op.typ.clone();
if op.tok_typ.clone() == TokenType::Word {
match op_type {
OpType::Instruction(InstructionType::None) => {
let m = self.functions.get(&op.text);
let mem = self.memories.get(&op.text);
let cons = self.constants.get(&op.text);
if let Some(m) = m {
// println!("------ FOUND FUNCTION {} -----------", m.name);
let mut t = op.clone();
t.typ = OpType::Instruction(InstructionType::FnCall);
t.text = m.name.clone();
program.push(t.clone());
// println!("##### {:?}", t);
} else if let Some(mem) = mem {
let mut t = op.clone();
t.addr = Some(mem.deref().id);
t.typ = OpType::Instruction(InstructionType::MemUse);
program.push(t);
} else if let Some(cons) = cons {
let mut t = op.clone();
t.text = cons.deref().name.clone();
t.typ = OpType::Instruction(InstructionType::ConstUse);
program.push(t);
} else {
lerror!(&op.loc, "Preprocess: Unknown word '{}'", op.text.clone());
return Err(eyre!(""));
}
}
_ => {
program.push(op.clone());
}
}
} else {
program.push(op.clone());
}
// if op.typ == OpType::Keyword(KeywordType::Do) {
// println!("expand: {:?}", op);
// program.push(op.clone());
// }
}
// println!("expand: has do tokens: {:?}", program.iter().map(|t| if t.typ == OpType::Keyword(KeywordType::Do) {Some(t)} else {None} ).collect::<Vec<Option<&Operator>>>());
self.program = program;
// println!("{:#?}", self.program);
println!("{:?}", self.program.last().unwrap());
Ok(())
}
pub fn get_ops(&mut self) -> Vec<Operator> {
self.program.clone()
}
pub fn is_word_available(&self, word: &Operator, typ: KeywordType) -> Result<bool> {
match typ {
KeywordType::Memory |
KeywordType::Constant |
KeywordType::Function => (),
_ => panic!()
}
if word.tok_typ != TokenType::Word {
lerror!(&word.loc, "Bad Function name, expected {} but found {}", TokenType::Word.human(), word.typ.human());
return Err(eyre!(""));
}
let m = self.memories.get(&word.text);
if let Some(m) = m {
if typ != KeywordType::Memory {
lerror!(&word.loc, "{typ:?} cannot replace memory, got {}", word.text);
linfo!(&m.loc, "first definition here");
return Err(eyre!(""));
} else {
lerror!(&word.loc, "Memories cannot be redefined, got {}", word.text);
linfo!(&m.loc, "first definition here");
return Err(eyre!(""));
}
}
let f = self.functions.get(&word.text);
if let Some(f) = f {
if typ != KeywordType::Function {
lerror!(&word.loc, "{typ:?} cannot replace function, got {}", word.text);
linfo!(&f.loc, "first definition here");
return Err(eyre!(""));
} else {
lerror!(&word.loc, "Functions cannot be redefined, got {}", word.text);
linfo!(&f.loc, "first definition here");
return Err(eyre!(""));
}
}
let c = self.constants.get(&word.text);
if let Some(c) = c {
if typ != KeywordType::Constant {
lerror!(&word.loc, "{typ:?} cannot replace constant, got {}", word.text);
linfo!(&c.loc, "first definition here");
return Err(eyre!(""));
} else {
lerror!(&word.loc, "Constants cannot be redefined, got {}", word.text);
linfo!(&c.loc, "first definition here");
return Err(eyre!(""));
}
}
Ok(true)
}
} }

View File

@ -1,19 +1,43 @@
use crate::{constants::{Operator, Types, OpType, KeywordType, InstructionType}, Args, lerror, warn}; use std::collections::HashMap;
use crate::{constants::{Operator, Types, OpType, KeywordType, InstructionType}, Args, lerror, warn, note};
use color_eyre::Result; use color_eyre::Result;
use eyre::eyre; use eyre::eyre;
#[derive(Debug, Clone)]
struct Function {
args: Vec<Types>,
returns: Vec<Types>,
}
impl Function {
pub fn default() -> Self {
Self {
args: Vec::new(),
returns: Vec::new(),
}
}
}
pub fn typecheck(ops: &[Operator], args: &Args) -> Result<Vec<Operator>>{ pub fn typecheck(ops: Vec<Operator>, args: &Args) -> Result<Vec<Operator>>{
if args.unsaf { if args.unsaf {
if !args.quiet { if !args.quiet {
warn!("Unsafe mode enabled, disabling typechecker, goodluck"); warn!("Unsafe mode enabled, disabling typechecker, goodluck");
} }
return Ok(ops.to_vec()); return Ok(ops.to_vec());
} }
let mut functions: HashMap<String, Function> = HashMap::new();
// let mut in_function: (String, Function) = (String::new(), Function::default());
let mut stack: Vec<Types> = Vec::new(); let mut stack: Vec<Types> = Vec::new();
let mut stack_snapshots: Vec<Vec<Types>> = Vec::new();
for op in ops { let mut rtokens = ops.clone();
rtokens.reverse();
// println!("{:#?}", ops);
while !rtokens.is_empty() {
let op = rtokens.pop().unwrap();
println!("{:?}", stack.clone());
// println!("{:?}", op);
// println!("{}", ops.len());
match op.typ.clone() { match op.typ.clone() {
OpType::Keyword(keyword) => { OpType::Keyword(keyword) => {
match keyword { match keyword {
@ -24,13 +48,94 @@ pub fn typecheck(ops: &[Operator], args: &Args) -> Result<Vec<Operator>>{
stack_pop(&mut stack, &op, &[Types::Bool])?; stack_pop(&mut stack, &op, &[Types::Bool])?;
}, },
KeywordType::Function => {
let name = op.text.clone();
if let Some(p) = rtokens.pop() {
if p.typ != OpType::Instruction(InstructionType::With){
lerror!(&op.loc, "Expected {:?}, got {:?}", OpType::Instruction(InstructionType::With), p.typ);
return Err(eyre!(""));
}
} else {
lerror!(&op.loc, "Expected {:?}, got nothing", OpType::Instruction(InstructionType::With));
return Err(eyre!(""));
}
let mut p = rtokens.pop();
let mut func = Function {
args: Vec::new(),
returns: Vec::new(),
};
let mut return_args = false;
while p.as_ref().is_some() {
let op = p.as_ref().unwrap();
if op.typ == OpType::Instruction(InstructionType::TypeBool) ||
op.typ == OpType::Instruction(InstructionType::TypeInt) ||
op.typ == OpType::Instruction(InstructionType::TypePtr) ||
op.typ == OpType::Instruction(InstructionType::TypeVoid) {
let t = if op.typ == OpType::Instruction(InstructionType::TypeInt) {
Types::Int
} else
if op.typ == OpType::Instruction(InstructionType::TypeBool) {
Types::Bool
} else
if op.typ == OpType::Instruction(InstructionType::TypePtr) {
Types::Ptr
} else
if op.typ == OpType::Instruction(InstructionType::TypeVoid) {
if return_args {
func.returns = vec![Types::Void];
} else {
func.args = vec![Types::Void];
return_args = true;
continue;
}
Types::Void
} else
if op.typ == OpType::Instruction(InstructionType::TypeStr) {
Types::Str
} else
if op.typ == OpType::Instruction(InstructionType::TypeAny) {
Types::Any
} else {
panic!()
};
if return_args {
func.returns.push(t);
} else {
func.args.push(t);
}
}
if op.typ == OpType::Instruction(InstructionType::Returns) {
return_args = true;
}
if op.typ == OpType::Keyword(KeywordType::FunctionDo) {
break;
}
p = rtokens.pop();
};
functions.insert(name.clone(), func.clone());
// if name == "main" {
// in_function = (name, func.clone());
// }
if func.args != vec![Types::Void] {
stack.append(&mut func.args);
}
stack_snapshots.push(stack.clone());
}
KeywordType::Else | KeywordType::Else |
KeywordType::End | KeywordType::End |
KeywordType::While | KeywordType::While |
KeywordType::Function |
KeywordType::Include | KeywordType::Include |
KeywordType::Constant | KeywordType::Constant |
KeywordType::Memory => (), KeywordType::Memory => (),
KeywordType::FunctionDo => (),
} }
}, },
OpType::Instruction(instruction) => { OpType::Instruction(instruction) => {
@ -76,42 +181,42 @@ pub fn typecheck(ops: &[Operator], args: &Args) -> Result<Vec<Operator>>{
}, },
InstructionType::Minus => { InstructionType::Minus => {
stack_pop(&mut stack, &op, &[Types::Int])?; stack_pop(&mut stack, &op, &[Types::Int])?;
stack_pop(&mut stack, &op, &[Types::Int, Types::Ptr])?; stack_pop(&mut stack, &op, &[Types::Int])?;
stack.push(Types::Int); stack.push(Types::Int);
}, },
InstructionType::Plus => { InstructionType::Plus => {
stack_pop(&mut stack, &op, &[Types::Int])?; stack_pop(&mut stack, &op, &[Types::Int])?;
stack_pop(&mut stack, &op, &[Types::Int, Types::Ptr])?; stack_pop(&mut stack, &op, &[Types::Int])?;
stack.push(Types::Int); stack.push(Types::Int);
}, },
InstructionType::Equals => { InstructionType::Equals => {
stack_pop(&mut stack, &op, &[Types::Int, Types::Ptr])?; stack_pop(&mut stack, &op, &[Types::Int])?;
stack_pop(&mut stack, &op, &[Types::Int, Types::Ptr])?; stack_pop(&mut stack, &op, &[Types::Int])?;
stack.push(Types::Bool); stack.push(Types::Bool);
}, },
InstructionType::Gt => { InstructionType::Gt => {
stack_pop(&mut stack, &op, &[Types::Int, Types::Ptr])?; stack_pop(&mut stack, &op, &[Types::Int])?;
stack_pop(&mut stack, &op, &[Types::Int, Types::Ptr])?; stack_pop(&mut stack, &op, &[Types::Int])?;
stack.push(Types::Bool); stack.push(Types::Bool);
}, },
InstructionType::Lt => { InstructionType::Lt => {
stack_pop(&mut stack, &op, &[Types::Int, Types::Ptr])?; stack_pop(&mut stack, &op, &[Types::Int])?;
stack_pop(&mut stack, &op, &[Types::Int, Types::Ptr])?; stack_pop(&mut stack, &op, &[Types::Int])?;
stack.push(Types::Bool); stack.push(Types::Bool);
}, },
InstructionType::Ge => { InstructionType::Ge => {
stack_pop(&mut stack, &op, &[Types::Int, Types::Ptr])?; stack_pop(&mut stack, &op, &[Types::Int])?;
stack_pop(&mut stack, &op, &[Types::Int, Types::Ptr])?; stack_pop(&mut stack, &op, &[Types::Int])?;
stack.push(Types::Bool); stack.push(Types::Bool);
}, },
InstructionType::Le => { InstructionType::Le => {
stack_pop(&mut stack, &op, &[Types::Int, Types::Ptr])?; stack_pop(&mut stack, &op, &[Types::Int])?;
stack_pop(&mut stack, &op, &[Types::Int, Types::Ptr])?; stack_pop(&mut stack, &op, &[Types::Int])?;
stack.push(Types::Bool); stack.push(Types::Bool);
}, },
InstructionType::NotEquals => { InstructionType::NotEquals => {
stack_pop(&mut stack, &op, &[Types::Int, Types::Ptr])?; stack_pop(&mut stack, &op, &[Types::Int])?;
stack_pop(&mut stack, &op, &[Types::Int, Types::Ptr])?; stack_pop(&mut stack, &op, &[Types::Int])?;
stack.push(Types::Bool); stack.push(Types::Bool);
}, },
InstructionType::Band => { InstructionType::Band => {
@ -145,9 +250,6 @@ pub fn typecheck(ops: &[Operator], args: &Args) -> Result<Vec<Operator>>{
stack_pop(&mut stack, &op, &[Types::Int])?; stack_pop(&mut stack, &op, &[Types::Int])?;
stack.push(Types::Int); stack.push(Types::Int);
}, },
InstructionType::Mem => {
stack.push(Types::Ptr);
},
InstructionType::Load8 => { InstructionType::Load8 => {
stack_pop(&mut stack, &op, &[Types::Ptr])?; stack_pop(&mut stack, &op, &[Types::Ptr])?;
stack.push(Types::Int); stack.push(Types::Int);
@ -233,18 +335,73 @@ pub fn typecheck(ops: &[Operator], args: &Args) -> Result<Vec<Operator>>{
stack_pop(&mut stack, &op, &[Types::Any])?; stack_pop(&mut stack, &op, &[Types::Any])?;
stack.push(Types::Int); stack.push(Types::Int);
}, },
InstructionType::CastVoid => {
stack_pop(&mut stack, &op, &[Types::Any])?;
stack.push(Types::Any);
},
InstructionType::MemUse => { InstructionType::MemUse => {
stack.push(Types::Ptr); stack.push(Types::Ptr);
}, },
InstructionType::FnCall | InstructionType::FnCall => {
InstructionType::Return | stack_snapshots.push(stack.clone());
let f = functions.get(&op.text).unwrap();
let mut s = stack.clone();
let mut a = f.args.clone();
// s.reverse();
a.reverse();
for t in a{
if let Some(s2) = s.pop(){
if t != s2 {
lerror!(&op.loc, "Expected {:?}, but got {:?}", t, s2);
return Err(eyre!(""));
}
} else {
lerror!(&op.loc, "Expected {:?}, but got nothing", t);
return Err(eyre!(""));
}
}
}
InstructionType::Return => {
let snap = stack_snapshots.pop().unwrap();
// snap.append(&mut f.returns.clone());
let mut st = stack.clone();
for s in snap{
if let Some(sn) = st.pop(){
if s != sn {
lerror!(&op.loc, "Expected {:?}, but got {:?}", s, sn);
return Err(eyre!(""));
}
} else {
lerror!(&op.loc, "Expected {:?}, but got nothing", s);
return Err(eyre!(""));
}
}
}
InstructionType::None => {}, InstructionType::None => {},
InstructionType::TypeBool |
InstructionType::TypePtr |
InstructionType::TypeInt |
InstructionType::TypeVoid |
InstructionType::TypeAny |
InstructionType::TypeStr |
InstructionType::Returns |
InstructionType::With => (),
InstructionType::ConstUse => todo!(),
} }
}, },
} }
}
Ok(ops.to_vec())
}
Ok(ops.clone())
} }

View File

@ -1,7 +1,5 @@
include "std.mcl" include "std.mcl"
fn main do fn main with void returns void do
69 putd
"henlo" puts end
end