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": {
"generator-code": "^1.7.4",
"vsce": "^2.15.0"
"@vscode/vsce": "^2.15.0"
}
}

View File

@ -53,7 +53,7 @@
{
"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",
@ -123,7 +123,7 @@
"patterns": [
{
"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__
macro !8 load8 end
macro @8 store8 end
end
// todo: add some sort of macro

View File

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

View File

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

View File

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

View File

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

View File

@ -5,7 +5,7 @@
// @arg str_len: Int
// @arg str_ptr: Ptr
// @ret NULL/NEVER
macro assert
fn assert with bool int ptr returns null do
rot
if else
"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>{
let debug = args.optimisation == "D";
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 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 mut writer = BufWriter::new(&file);
let mut memories: Vec<(usize, usize)> = Vec::new();
let mut constants: Vec<(String, Option<usize>, Option<String>)> = Vec::new();
// println!("{}", tokens.len());
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, "global _start")?;
writeln!(writer, "_start:")?;
writeln!(writer, "_start:")?;
writeln!(writer, " lea rbp, [rel ret_stack]")?;
writeln!(writer, " call func_main")?;
writeln!(writer, " jmp end")?;
@ -76,41 +80,73 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
let mut ti = 0;
while ti < tokens.len() {
let token = &tokens[ti];
println!("{:?}", token);
writeln!(writer, "addr_{ti}:")?;
// println!("{:?}", token);
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() {
// stack
OpType::Instruction(instruction) => {
match instruction {
InstructionType::PushInt => {
writeln!(writer, " ;; -- push int {}", token.value)?;
writeln!(writer, " mov rax, {}", token.value)?;
writeln!(writer, " push rax")?;
ti += 1;
},
InstructionType::PushStr => {
writeln!(writer, " ;; -- push str \"{}\"", token.text.escape_default())?;
writeln!(writer, " mov rax, {}", token.text.len())?;
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());
ti += 1;
}
InstructionType::Drop => {
writeln!(writer, " ;; -- drop")?;
writeln!(writer, " pop rax")?;
ti += 1;
},
InstructionType::Print => {
writeln!(writer, " ;; -- print")?;
writeln!(writer, " pop rdi")?;
writeln!(writer, " call print")?;
ti += 1;
},
InstructionType::Dup => {
writeln!(writer, " ;; -- dup")?;
writeln!(writer, " pop rax")?;
writeln!(writer, " push rax")?;
writeln!(writer, " push rax")?;
@ -119,7 +155,6 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
},
InstructionType::Rot => {
writeln!(writer, " ;; -- rot")?;
writeln!(writer, " pop rax")?;
writeln!(writer, " pop rbx")?;
writeln!(writer, " pop rcx")?;
@ -130,7 +165,6 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
ti += 1;
},
InstructionType::Swap => {
writeln!(writer, " ;; -- swap")?;
writeln!(writer, " pop rax")?;
writeln!(writer, " pop rbx")?;
writeln!(writer, " push rax")?;
@ -139,7 +173,6 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
ti += 1;
},
InstructionType::Over => {
writeln!(writer, " ;; -- over")?;
writeln!(writer, " pop rax")?;
writeln!(writer, " pop rbx")?;
writeln!(writer, " push rbx")?;
@ -148,15 +181,7 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
ti += 1;
},
//mem
InstructionType::Mem => {
writeln!(writer, " ;; -- mem")?;
writeln!(writer, " push mem")?;
ti += 1;
}
InstructionType::Load8 => {
writeln!(writer, " ;; -- load")?;
writeln!(writer, " pop rax")?;
writeln!(writer, " xor rbx, rbx")?;
writeln!(writer, " mov bl, byte [rax]")?;
@ -165,14 +190,12 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
}
InstructionType::Store8 => {
writeln!(writer, " ;; -- store")?;
writeln!(writer, " pop rbx")?;
writeln!(writer, " pop rax")?;
writeln!(writer, " mov byte [rax], bl")?;
ti += 1;
}
InstructionType::Load32 => {
writeln!(writer, " ;; -- load")?;
writeln!(writer, " pop rax")?;
writeln!(writer, " xor rbx, rbx")?;
writeln!(writer, " mov bl, dword [rax]")?;
@ -181,14 +204,12 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
}
InstructionType::Store32 => {
writeln!(writer, " ;; -- store")?;
writeln!(writer, " pop rbx")?;
writeln!(writer, " pop rax")?;
writeln!(writer, " mov dword[rax], bl")?;
ti += 1;
}
InstructionType::Load64 => {
writeln!(writer, " ;; -- load")?;
writeln!(writer, " pop rax")?;
writeln!(writer, " xor rbx, rbx")?;
writeln!(writer, " mov bl, qword [rax]")?;
@ -197,7 +218,6 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
}
InstructionType::Store64 => {
writeln!(writer, " ;; -- store")?;
writeln!(writer, " pop rbx")?;
writeln!(writer, " pop rax")?;
writeln!(writer, " mov qword [rax], bl")?;
@ -206,7 +226,6 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
// math
InstructionType::Plus => {
writeln!(writer, " ;; -- plus")?;
writeln!(writer, " pop rax")?;
writeln!(writer, " pop rbx")?;
writeln!(writer, " add rax, rbx")?;
@ -214,7 +233,6 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
ti += 1;
},
InstructionType::Minus => {
writeln!(writer, " ;; -- minus")?;
writeln!(writer, " pop rax")?;
writeln!(writer, " pop rbx")?;
writeln!(writer, " sub rbx, rax")?;
@ -222,7 +240,6 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
ti += 1;
},
InstructionType::Equals => {
writeln!(writer, " ;; -- equals")?;
writeln!(writer, " mov rcx, 0")?;
writeln!(writer, " mov rdx, 1")?;
writeln!(writer, " pop rax")?;
@ -233,7 +250,6 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
ti += 1;
},
InstructionType::Lt => {
writeln!(writer, " ;; -- lt")?;
writeln!(writer, " mov rcx, 0")?;
writeln!(writer, " mov rdx, 1")?;
writeln!(writer, " pop rbx")?;
@ -244,7 +260,6 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
ti += 1;
},
InstructionType::Gt => {
writeln!(writer, " ;; -- gt")?;
writeln!(writer, " mov rcx, 0")?;
writeln!(writer, " mov rdx, 1")?;
writeln!(writer, " pop rbx")?;
@ -255,7 +270,6 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
ti += 1;
},
InstructionType::NotEquals => {
writeln!(writer, " ;; -- not equals")?;
writeln!(writer, " mov rcx, 1")?;
writeln!(writer, " mov rdx, 0")?;
writeln!(writer, " pop rax")?;
@ -266,7 +280,6 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
ti += 1;
},
InstructionType::Le => {
writeln!(writer, " ;; -- lt")?;
writeln!(writer, " mov rcx, 0")?;
writeln!(writer, " mov rdx, 1")?;
writeln!(writer, " pop rbx")?;
@ -277,7 +290,6 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
ti += 1;
},
InstructionType::Ge => {
writeln!(writer, " ;; -- gt")?;
writeln!(writer, " mov rcx, 0")?;
writeln!(writer, " mov rdx, 1")?;
writeln!(writer, " pop rbx")?;
@ -288,7 +300,6 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
ti += 1;
},
InstructionType::Band => {
writeln!(writer, " ;; -- band")?;
writeln!(writer, " pop rax")?;
writeln!(writer, " pop rbx")?;
writeln!(writer, " and rbx, rax")?;
@ -296,7 +307,6 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
ti += 1;
},
InstructionType::Bor => {
writeln!(writer, " ;; -- bor")?;
writeln!(writer, " pop rax")?;
writeln!(writer, " pop rbx")?;
writeln!(writer, " or rbx, rax")?;
@ -304,7 +314,6 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
ti += 1;
},
InstructionType::Shr => {
writeln!(writer, " ;; -- shr")?;
writeln!(writer, " pop rcx")?;
writeln!(writer, " pop rbx")?;
writeln!(writer, " shr rbx, cl")?;
@ -312,7 +321,6 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
ti += 1;
},
InstructionType::Shl => {
writeln!(writer, " ;; -- shl")?;
writeln!(writer, " pop rcx")?;
writeln!(writer, " pop rbx")?;
writeln!(writer, " shl rbx, cl")?;
@ -320,7 +328,6 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
ti += 1;
},
InstructionType::DivMod => {
writeln!(writer, " ;; -- div")?;
writeln!(writer, " xor rdx, rdx")?;
writeln!(writer, " pop rbx")?;
writeln!(writer, " pop rax")?;
@ -330,7 +337,6 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
ti += 1;
},
InstructionType::Mul => {
writeln!(writer, " ;; -- mul")?;
writeln!(writer, " pop rax")?;
writeln!(writer, " pop rbx")?;
writeln!(writer, " mul rbx")?;
@ -338,14 +344,12 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
ti += 1;
},
InstructionType::Syscall0 => {
writeln!(writer, " ;; -- syscall0")?;
writeln!(writer, " pop rax")?;
writeln!(writer, " syscall")?;
writeln!(writer, " push rax")?;
ti += 1;
},
InstructionType::Syscall1 => {
writeln!(writer, " ;; -- syscall1")?;
writeln!(writer, " pop rax")?;
writeln!(writer, " pop rdi")?;
writeln!(writer, " syscall")?;
@ -353,7 +357,6 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
ti += 1;
},
InstructionType::Syscall2 => {
writeln!(writer, " ;; -- syscall2")?;
writeln!(writer, " pop rax")?;
writeln!(writer, " pop rdi")?;
writeln!(writer, " pop rsi")?;
@ -362,7 +365,6 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
ti += 1;
},
InstructionType::Syscall3 => {
writeln!(writer, " ;; -- syscall3")?;
writeln!(writer, " pop rax")?;
writeln!(writer, " pop rdi")?;
writeln!(writer, " pop rsi")?;
@ -373,7 +375,6 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
ti += 1;
},
InstructionType::Syscall4 => {
writeln!(writer, " ;; -- syscall4")?;
writeln!(writer, " pop rax")?;
writeln!(writer, " pop rdi")?;
writeln!(writer, " pop rsi")?;
@ -384,7 +385,6 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
ti += 1;
},
InstructionType::Syscall5 => {
writeln!(writer, " ;; -- syscall5")?;
writeln!(writer, " pop rax")?;
writeln!(writer, " pop rdi")?;
writeln!(writer, " pop rsi")?;
@ -396,7 +396,6 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
ti += 1;
},
InstructionType::Syscall6 => {
writeln!(writer, " ;; -- syscall6")?;
writeln!(writer, " pop rax")?;
writeln!(writer, " pop rdi")?;
writeln!(writer, " pop rsi")?;
@ -409,24 +408,65 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
ti += 1;
},
InstructionType::MemUse => {
writeln!(writer, " ;; -- MemUse")?;
writeln!(writer, " push mem_{}", token.addr.unwrap())?;
ti += 1;
},
InstructionType::None => unreachable!(),
InstructionType::CastBool => ti += 1,
InstructionType::CastPtr => ti += 1,
InstructionType::CastInt => ti += 1,
InstructionType::None => {
println!("{:?}", token);
unreachable!()
},
InstructionType::FnCall => {
writeln!(writer, " ;; -- FnCall")?;
writeln!(writer, " call func_{}", token.text)?;
ti += 1;
},
InstructionType::Return => {
writeln!(writer, " ;; -- Return")?;
writeln!(writer, " sub rbp, 8")?;
writeln!(writer, " mov rbx, qword [rbp]")?;
writeln!(writer, " push rbx")?;
writeln!(writer, " ret")?;
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
KeywordType::If => {
writeln!(writer, " ;; -- if")?;
writeln!(writer, " pop rax")?;
writeln!(writer, " test rax, rax")?;
writeln!(writer, " jz addr_{}", token.jmp)?;
ti += 1;
},
KeywordType::Else => {
writeln!(writer, " ;; -- else")?;
writeln!(writer, " jmp addr_{}", token.jmp)?;
ti += 1;
},
KeywordType::While => {
writeln!(writer, " ;; -- while")?;
ti += 1;
}
KeywordType::Do => {
writeln!(writer, " ;; -- do")?;
writeln!(writer, " pop rax")?;
writeln!(writer, " test rax, rax")?;
writeln!(writer, " jz addr_{}", token.jmp)?;
ti += 1;
}
KeywordType::End => {
writeln!(writer, " ;; -- end")?;
if ti + 1 != token.jmp {
writeln!(writer, " jmp addr_{}", token.jmp)?;
// writeln!(writer, " jmp addr_{}", token.jmp)?;
}
ti += 1;
},
@ -470,11 +505,19 @@ pub fn compile(tokens: &[Operator], args: &Args) -> Result<i32>{
ti += 1;
}
KeywordType::Include => unreachable!(),
KeywordType::Constant => todo!(),
KeywordType::Function => {
writeln!(writer, "func_{}:", token.text)?;
KeywordType::Constant => {
// TODO: after we add c style strings add supoort for them in constants
constants.push((token.text.clone(), Some(token.value), None));
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())?;
}
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")?;
for (_, s) in memories.iter().enumerate() {
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()?;
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);
}
Ok(0)
}

View File

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

View File

@ -96,12 +96,6 @@ pub fn run(tokens: &[crate::constants::Operator]) -> Result<i32>{
// let _ = io::stdout().flush();
ti += 1;
},
// mem
InstructionType::Mem => {
stack.push(0);
ti += 1;
}
InstructionType::Load8 |
InstructionType::Load32 |
InstructionType::Load64 => {
@ -294,12 +288,22 @@ pub fn run(tokens: &[crate::constants::Operator]) -> Result<i32>{
stack.push(*m);
ti += 1;
},
InstructionType::CastBool => ti += 1,
InstructionType::CastPtr => ti += 1,
InstructionType::CastInt => ti += 1,
InstructionType::CastBool |
InstructionType::CastPtr |
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::FnCall => todo!(),
InstructionType::Return => todo!(),
InstructionType::ConstUse => todo!(),
}
}
@ -336,6 +340,7 @@ pub fn run(tokens: &[crate::constants::Operator]) -> Result<i32>{
KeywordType::Include => unreachable!(),
KeywordType::Constant => 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;
fn lex_word(s: String, tok_type: TokenType) -> (TokenType, String) {
@ -89,7 +89,7 @@ fn lex_line(text: &str) -> Vec<(usize, String, TokenType)> {
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
.split(['\n', '\r'])
.enumerate()

View File

@ -53,8 +53,12 @@ pub struct Args {
/// Unsafe mode, disables typechecking
#[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')]
//features: Vec<String>,
@ -82,7 +86,7 @@ fn main() {
return;
};
let Ok(tokens) = typechecker::typecheck(&tokens, &args) else {
let Ok(tokens) = typechecker::typecheck(tokens, &args) else {
error!("Typechecking failed, exiting!");
return;
};

View File

@ -1,11 +1,12 @@
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 eyre::eyre;
pub fn cross_ref(mut program: Vec<Operator>) -> Result<Vec<Operator>> {
let mut stack: Vec<usize> = Vec::new();
for ip in 0..program.len() {
let op = &program.clone()[ip];
match op.typ {
@ -15,9 +16,12 @@ pub fn cross_ref(mut program: Vec<Operator>) -> Result<Vec<Operator>> {
stack.push(ip);
}
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) {
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"));
}
@ -25,36 +29,48 @@ pub fn cross_ref(mut program: Vec<Operator>) -> Result<Vec<Operator>> {
stack.push(ip);
},
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) ||
program[block_ip].typ == OpType::Keyword(KeywordType::Else) {
program[block_ip].jmp = ip;
program[ip].jmp = ip + 1;
OpType::Keyword(KeywordType::Do) => {
program[ip].jmp = program[block_ip].jmp;
program[block_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) {
program[ip].jmp = program[block_ip].jmp;
program[block_ip].jmp = ip + 1;
} else if program[block_ip].typ == OpType::Keyword(KeywordType::Function) {
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!(""));
a => {
println!("{a:?}");
lerror!(&op.clone().loc,"'end' can only close if, if-else, while-do, function, memory, or constant blocks");
return Err(eyre!(""));
}
}
}
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) {
program[ip].typ = OpType::Keyword(KeywordType::Function);
program[ip].typ = OpType::Keyword(KeywordType::FunctionDo);
}
program[ip].jmp = block_ip;
// println!("{}", block_ip);
stack.push(ip);
}
_ => ()
@ -63,7 +79,7 @@ pub fn cross_ref(mut program: Vec<Operator>) -> Result<Vec<Operator>> {
}
if !stack.is_empty() {
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"));
}
@ -116,14 +132,13 @@ impl Parser {
}
};
//"print" => tokens.push(Operator::new(OpType::Print, 0, token.file.clone(), token.line, token.col)),
}
tokens = cross_ref(tokens.clone())?;
let t = preprocess(tokens, args)?;
Ok(t.0)
let t = Preprocessor::new(tokens.clone(), args).preprocess()?.get_ops();
let t = cross_ref(t.clone())?;
Ok(t)
}
}
@ -161,7 +176,6 @@ pub fn lookup_word<P: Deref<Target = Loc>>(s: &str, _pos: P) -> OpType {
// mem
"mem" => OpType::Instruction(InstructionType::Mem),
"load8" => OpType::Instruction(InstructionType::Load8),
"store8" => OpType::Instruction(InstructionType::Store8),
"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),
"syscall5" => OpType::Instruction(InstructionType::Syscall5),
"syscall6" => OpType::Instruction(InstructionType::Syscall6),
"cast(bool" => OpType::Instruction(InstructionType::CastBool),
"cast(bool)" => OpType::Instruction(InstructionType::CastBool),
"cast(ptr)" => OpType::Instruction(InstructionType::CastPtr),
"cast(int)" => OpType::Instruction(InstructionType::CastInt),
"cast(void)" => OpType::Instruction(InstructionType::CastVoid),
// block
"if" => OpType::Keyword(KeywordType::If),
"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),
"const" => OpType::Keyword(KeywordType::Constant),
"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)
}

View File

@ -2,7 +2,7 @@
use color_eyre::Result;
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> {
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>>{
let mut stack: Vec<usize> = Vec::new();
for token in tokens.iter() {
match token.typ.clone() {
OpType::Instruction(i) => {
let loc = token.loc.clone();
match i {
InstructionType::PushInt => {
if let Ok(i) = token.text.parse::<usize>() {
stack.push(i);
} else {
lerror!(&token.loc, "Bad number");
return Err(eyre!(""));
}
stack.push(token.value);
},
InstructionType::Plus => {
let a = stack_pop(&mut stack, &loc)?;

View File

@ -1,251 +1,364 @@
use std::collections::HashMap;
use std::ops::Deref;
use std::path::{PathBuf, Path};
use color_eyre::Result;
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::precompiler::precompile;
use crate::{lerror, lnote, Args, warn, linfo, parser};
use crate::{lerror, Args, warn, linfo, parser};
use crate::parser::lookup_word;
#[derive(Debug)]
pub struct Function {
pub loc: Loc,
pub name: String
}
type Functions = HashMap<String, Function>;
type Memories = HashMap<String, usize>;
pub fn preprocess(tokens: Vec<Operator>, args: &Args) -> Result<(Vec<Operator>, Functions)>{
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))
#[derive(Debug)]
pub struct Constant {
pub loc: Loc,
pub name: String
}
pub fn expand(tokens: Vec<Operator>, funcs: &Functions, mems: &Memories) -> Result<Vec<Operator>> {
let mut program: Vec<Operator> = Vec::new();
#[derive(Debug)]
pub struct Memory {
pub loc: Loc,
pub id: usize
}
let mut rtokens = tokens.clone();
rtokens.reverse();
type Functions = HashMap<String, Function>;
type Memories = HashMap<String, Memory>;
type Constants = HashMap<String, Constant>;
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 = funcs.get(&op.text);
let mem = mems.get(&op.text);
if let Some(m) = m {
let mut t = op.clone();
t.typ = OpType::Instruction(InstructionType::FnCall);
t.text = m.name.clone();
program.push(t);
} else
if let Some(mem) = mem {
let mut t = op.clone();
t.addr = Some(*mem);
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());
pub struct Preprocessor<'a> {
program: Vec<Operator>,
functions: Functions,
memories: Memories,
constants: Constants,
args: &'a Args
}
impl<'a> Preprocessor<'a> {
pub fn new(prog: Vec<Operator>, args: &'a Args) -> Self {
Self {
program: prog,
args: args,
functions: HashMap::new(),
memories: HashMap::new(),
constants: HashMap::new(),
}
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 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.quiet {
warn!("Unsafe mode enabled, disabling typechecker, goodluck");
}
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();
for op in ops {
let mut stack_snapshots: Vec<Vec<Types>> = Vec::new();
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() {
OpType::Keyword(keyword) => {
match keyword {
@ -24,13 +48,94 @@ pub fn typecheck(ops: &[Operator], args: &Args) -> Result<Vec<Operator>>{
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::End |
KeywordType::While |
KeywordType::Function |
KeywordType::Include |
KeywordType::Constant |
KeywordType::Memory => (),
KeywordType::FunctionDo => (),
}
},
OpType::Instruction(instruction) => {
@ -76,42 +181,42 @@ pub fn typecheck(ops: &[Operator], args: &Args) -> Result<Vec<Operator>>{
},
InstructionType::Minus => {
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);
},
InstructionType::Plus => {
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);
},
InstructionType::Equals => {
stack_pop(&mut stack, &op, &[Types::Int, Types::Ptr])?;
stack_pop(&mut stack, &op, &[Types::Int, Types::Ptr])?;
stack_pop(&mut stack, &op, &[Types::Int])?;
stack_pop(&mut stack, &op, &[Types::Int])?;
stack.push(Types::Bool);
},
InstructionType::Gt => {
stack_pop(&mut stack, &op, &[Types::Int, Types::Ptr])?;
stack_pop(&mut stack, &op, &[Types::Int, Types::Ptr])?;
stack_pop(&mut stack, &op, &[Types::Int])?;
stack_pop(&mut stack, &op, &[Types::Int])?;
stack.push(Types::Bool);
},
InstructionType::Lt => {
stack_pop(&mut stack, &op, &[Types::Int, Types::Ptr])?;
stack_pop(&mut stack, &op, &[Types::Int, Types::Ptr])?;
stack_pop(&mut stack, &op, &[Types::Int])?;
stack_pop(&mut stack, &op, &[Types::Int])?;
stack.push(Types::Bool);
},
InstructionType::Ge => {
stack_pop(&mut stack, &op, &[Types::Int, Types::Ptr])?;
stack_pop(&mut stack, &op, &[Types::Int, Types::Ptr])?;
stack_pop(&mut stack, &op, &[Types::Int])?;
stack_pop(&mut stack, &op, &[Types::Int])?;
stack.push(Types::Bool);
},
InstructionType::Le => {
stack_pop(&mut stack, &op, &[Types::Int, Types::Ptr])?;
stack_pop(&mut stack, &op, &[Types::Int, Types::Ptr])?;
stack_pop(&mut stack, &op, &[Types::Int])?;
stack_pop(&mut stack, &op, &[Types::Int])?;
stack.push(Types::Bool);
},
InstructionType::NotEquals => {
stack_pop(&mut stack, &op, &[Types::Int, Types::Ptr])?;
stack_pop(&mut stack, &op, &[Types::Int, Types::Ptr])?;
stack_pop(&mut stack, &op, &[Types::Int])?;
stack_pop(&mut stack, &op, &[Types::Int])?;
stack.push(Types::Bool);
},
InstructionType::Band => {
@ -145,9 +250,6 @@ pub fn typecheck(ops: &[Operator], args: &Args) -> Result<Vec<Operator>>{
stack_pop(&mut stack, &op, &[Types::Int])?;
stack.push(Types::Int);
},
InstructionType::Mem => {
stack.push(Types::Ptr);
},
InstructionType::Load8 => {
stack_pop(&mut stack, &op, &[Types::Ptr])?;
stack.push(Types::Int);
@ -233,18 +335,73 @@ pub fn typecheck(ops: &[Operator], args: &Args) -> Result<Vec<Operator>>{
stack_pop(&mut stack, &op, &[Types::Any])?;
stack.push(Types::Int);
},
InstructionType::CastVoid => {
stack_pop(&mut stack, &op, &[Types::Any])?;
stack.push(Types::Any);
},
InstructionType::MemUse => {
stack.push(Types::Ptr);
},
InstructionType::FnCall |
InstructionType::Return |
InstructionType::FnCall => {
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::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"
fn main do
"henlo" puts
end
fn main with void returns void do
69 putd
end