include "statement"
This commit is contained in:
30
src/main.rs
30
src/main.rs
@@ -12,15 +12,6 @@ use std::{
|
||||
|
||||
use tokenizer::ZernError;
|
||||
|
||||
macro_rules! parse_std_file {
|
||||
($statements:expr, $filename:expr) => {
|
||||
let source: String = include_str!($filename).into();
|
||||
let tokenizer = tokenizer::Tokenizer::new($filename.to_owned(), source);
|
||||
let parser = parser::Parser::new(tokenizer.tokenize()?);
|
||||
$statements.extend(parser.parse()?);
|
||||
};
|
||||
}
|
||||
|
||||
fn compile_file(args: Args) -> Result<(), ZernError> {
|
||||
let source = match fs::read_to_string(&args.path) {
|
||||
Ok(x) => x,
|
||||
@@ -32,17 +23,10 @@ fn compile_file(args: Args) -> Result<(), ZernError> {
|
||||
|
||||
let filename = Path::new(&args.path).file_name().unwrap().to_str().unwrap();
|
||||
|
||||
let mut statements = Vec::new();
|
||||
|
||||
if args.include_stdlib {
|
||||
parse_std_file!(statements, "std/std.zr");
|
||||
parse_std_file!(statements, "std/net.zr");
|
||||
parse_std_file!(statements, "std/linux_constants.zr");
|
||||
}
|
||||
|
||||
let tokenizer = tokenizer::Tokenizer::new(filename.to_owned(), source);
|
||||
let mut tokenizer = tokenizer::Tokenizer::new(filename.to_owned(), source);
|
||||
tokenizer.include_file("std/std.zr".into())?;
|
||||
let parser = parser::Parser::new(tokenizer.tokenize()?);
|
||||
statements.extend(parser.parse()?);
|
||||
let statements = parser.parse()?;
|
||||
|
||||
let mut symbol_table = symbol_table::SymbolTable::new();
|
||||
for stmt in &statements {
|
||||
@@ -114,7 +98,6 @@ struct Args {
|
||||
out: Option<String>,
|
||||
emit_only: bool,
|
||||
emit_debug: bool,
|
||||
include_stdlib: bool,
|
||||
run_exe: bool,
|
||||
use_crt: bool,
|
||||
cflags: String,
|
||||
@@ -129,7 +112,6 @@ impl Args {
|
||||
out: None,
|
||||
emit_only: false,
|
||||
emit_debug: false,
|
||||
include_stdlib: true,
|
||||
run_exe: false,
|
||||
use_crt: false,
|
||||
cflags: String::new(),
|
||||
@@ -146,8 +128,6 @@ impl Args {
|
||||
}
|
||||
} else if arg == "--emit-only" {
|
||||
out.emit_only = true;
|
||||
} else if arg == "--no-stdlib" {
|
||||
out.include_stdlib = false;
|
||||
} else if arg == "-r" {
|
||||
out.run_exe = true;
|
||||
} else if arg == "-m" {
|
||||
@@ -163,9 +143,7 @@ impl Args {
|
||||
}
|
||||
}
|
||||
} else if arg == "-h" || arg == "--help" {
|
||||
println!(
|
||||
"Usage: zern [-o path] [-r] [-m] [-g] [-C cflags] [--emit-only] [--no-stdlib] path"
|
||||
);
|
||||
println!("Usage: zern [-o path] [-r] [-m] [-g] [-C cflags] [--emit-only] path");
|
||||
process::exit(0);
|
||||
} else if arg.starts_with('-') {
|
||||
eprintln!("\x1b[91mERROR\x1b[0m: unrecognized option: {arg}");
|
||||
|
||||
@@ -1,406 +0,0 @@
|
||||
const STDIN = 0
|
||||
const STDOUT = 1
|
||||
|
||||
const SIGABRT = 6
|
||||
|
||||
const AT_FDCWD = -100
|
||||
|
||||
const S_IFDIR = 0o040000
|
||||
const S_IFMT = 0o170000
|
||||
|
||||
const PROT_READ = 1
|
||||
const PROT_WRITE = 2
|
||||
|
||||
const MAP_PRIVATE = 2
|
||||
const MAP_ANONYMOUS = 32
|
||||
|
||||
const O_RDONLY = 0
|
||||
const O_WRONLY = 1
|
||||
const O_CREAT = 64
|
||||
const O_TRUNC = 512
|
||||
|
||||
const SEEK_SET = 0
|
||||
const SEEK_END = 2
|
||||
|
||||
const F_OK = 0
|
||||
|
||||
const SYS_read = 0
|
||||
const SYS_write = 1
|
||||
const SYS_open = 2
|
||||
const SYS_close = 3
|
||||
const SYS_stat = 4
|
||||
const SYS_fstat = 5
|
||||
const SYS_lstat = 6
|
||||
const SYS_poll = 7
|
||||
const SYS_lseek = 8
|
||||
const SYS_mmap = 9
|
||||
const SYS_mprotect = 10
|
||||
const SYS_munmap = 11
|
||||
const SYS_brk = 12
|
||||
const SYS_rt_sigaction = 13
|
||||
const SYS_rt_sigprocmask = 14
|
||||
const SYS_rt_sigreturn = 15
|
||||
const SYS_ioctl = 16
|
||||
const SYS_pread64 = 17
|
||||
const SYS_pwrite64 = 18
|
||||
const SYS_readv = 19
|
||||
const SYS_writev = 20
|
||||
const SYS_access = 21
|
||||
const SYS_pipe = 22
|
||||
const SYS_select = 23
|
||||
const SYS_sched_yield = 24
|
||||
const SYS_mremap = 25
|
||||
const SYS_msync = 26
|
||||
const SYS_mincore = 27
|
||||
const SYS_madvise = 28
|
||||
const SYS_shmget = 29
|
||||
const SYS_shmat = 30
|
||||
const SYS_shmctl = 31
|
||||
const SYS_dup = 32
|
||||
const SYS_dup2 = 33
|
||||
const SYS_pause = 34
|
||||
const SYS_nanosleep = 35
|
||||
const SYS_getitimer = 36
|
||||
const SYS_alarm = 37
|
||||
const SYS_setitimer = 38
|
||||
const SYS_getpid = 39
|
||||
const SYS_sendfile = 40
|
||||
const SYS_socket = 41
|
||||
const SYS_connect = 42
|
||||
const SYS_accept = 43
|
||||
const SYS_sendto = 44
|
||||
const SYS_recvfrom = 45
|
||||
const SYS_sendmsg = 46
|
||||
const SYS_recvmsg = 47
|
||||
const SYS_shutdown = 48
|
||||
const SYS_bind = 49
|
||||
const SYS_listen = 50
|
||||
const SYS_getsockname = 51
|
||||
const SYS_getpeername = 52
|
||||
const SYS_socketpair = 53
|
||||
const SYS_setsockopt = 54
|
||||
const SYS_getsockopt = 55
|
||||
const SYS_clone = 56
|
||||
const SYS_fork = 57
|
||||
const SYS_vfork = 58
|
||||
const SYS_execve = 59
|
||||
const SYS_exit = 60
|
||||
const SYS_wait4 = 61
|
||||
const SYS_kill = 62
|
||||
const SYS_uname = 63
|
||||
const SYS_semget = 64
|
||||
const SYS_semop = 65
|
||||
const SYS_semctl = 66
|
||||
const SYS_shmdt = 67
|
||||
const SYS_msgget = 68
|
||||
const SYS_msgsnd = 69
|
||||
const SYS_msgrcv = 70
|
||||
const SYS_msgctl = 71
|
||||
const SYS_fcntl = 72
|
||||
const SYS_flock = 73
|
||||
const SYS_fsync = 74
|
||||
const SYS_fdatasync = 75
|
||||
const SYS_truncate = 76
|
||||
const SYS_ftruncate = 77
|
||||
const SYS_getdents = 78
|
||||
const SYS_getcwd = 79
|
||||
const SYS_chdir = 80
|
||||
const SYS_fchdir = 81
|
||||
const SYS_rename = 82
|
||||
const SYS_mkdir = 83
|
||||
const SYS_rmdir = 84
|
||||
const SYS_creat = 85
|
||||
const SYS_link = 86
|
||||
const SYS_unlink = 87
|
||||
const SYS_symlink = 88
|
||||
const SYS_readlink = 89
|
||||
const SYS_chmod = 90
|
||||
const SYS_fchmod = 91
|
||||
const SYS_chown = 92
|
||||
const SYS_fchown = 93
|
||||
const SYS_lchown = 94
|
||||
const SYS_umask = 95
|
||||
const SYS_gettimeofday = 96
|
||||
const SYS_getrlimit = 97
|
||||
const SYS_getrusage = 98
|
||||
const SYS_sysinfo = 99
|
||||
const SYS_times = 100
|
||||
const SYS_ptrace = 101
|
||||
const SYS_getuid = 102
|
||||
const SYS_syslog = 103
|
||||
const SYS_getgid = 104
|
||||
const SYS_setuid = 105
|
||||
const SYS_setgid = 106
|
||||
const SYS_geteuid = 107
|
||||
const SYS_getegid = 108
|
||||
const SYS_setpgid = 109
|
||||
const SYS_getppid = 110
|
||||
const SYS_getpgrp = 111
|
||||
const SYS_setsid = 112
|
||||
const SYS_setreuid = 113
|
||||
const SYS_setregid = 114
|
||||
const SYS_getgroups = 115
|
||||
const SYS_setgroups = 116
|
||||
const SYS_setresuid = 117
|
||||
const SYS_getresuid = 118
|
||||
const SYS_setresgid = 119
|
||||
const SYS_getresgid = 120
|
||||
const SYS_getpgid = 121
|
||||
const SYS_setfsuid = 122
|
||||
const SYS_setfsgid = 123
|
||||
const SYS_getsid = 124
|
||||
const SYS_capget = 125
|
||||
const SYS_capset = 126
|
||||
const SYS_rt_sigpending = 127
|
||||
const SYS_rt_sigtimedwait = 128
|
||||
const SYS_rt_sigqueueinfo = 129
|
||||
const SYS_rt_sigsuspend = 130
|
||||
const SYS_sigaltstack = 131
|
||||
const SYS_utime = 132
|
||||
const SYS_mknod = 133
|
||||
const SYS_uselib = 134
|
||||
const SYS_personality = 135
|
||||
const SYS_ustat = 136
|
||||
const SYS_statfs = 137
|
||||
const SYS_fstatfs = 138
|
||||
const SYS_sysfs = 139
|
||||
const SYS_getpriority = 140
|
||||
const SYS_setpriority = 141
|
||||
const SYS_sched_setparam = 142
|
||||
const SYS_sched_getparam = 143
|
||||
const SYS_sched_setscheduler = 144
|
||||
const SYS_sched_getscheduler = 145
|
||||
const SYS_sched_get_priority_max = 146
|
||||
const SYS_sched_get_priority_min = 147
|
||||
const SYS_sched_rr_get_interval = 148
|
||||
const SYS_mlock = 149
|
||||
const SYS_munlock = 150
|
||||
const SYS_mlockall = 151
|
||||
const SYS_munlockall = 152
|
||||
const SYS_vhangup = 153
|
||||
const SYS_modify_ldt = 154
|
||||
const SYS_pivot_root = 155
|
||||
const SYS__sysctl = 156
|
||||
const SYS_prctl = 157
|
||||
const SYS_arch_prctl = 158
|
||||
const SYS_adjtimex = 159
|
||||
const SYS_setrlimit = 160
|
||||
const SYS_chroot = 161
|
||||
const SYS_sync = 162
|
||||
const SYS_acct = 163
|
||||
const SYS_settimeofday = 164
|
||||
const SYS_mount = 165
|
||||
const SYS_umount2 = 166
|
||||
const SYS_swapon = 167
|
||||
const SYS_swapoff = 168
|
||||
const SYS_reboot = 169
|
||||
const SYS_sethostname = 170
|
||||
const SYS_setdomainname = 171
|
||||
const SYS_iopl = 172
|
||||
const SYS_ioperm = 173
|
||||
const SYS_create_module = 174
|
||||
const SYS_init_module = 175
|
||||
const SYS_delete_module = 176
|
||||
const SYS_get_kernel_syms = 177
|
||||
const SYS_query_module = 178
|
||||
const SYS_quotactl = 179
|
||||
const SYS_nfsservctl = 180
|
||||
const SYS_getpmsg = 181
|
||||
const SYS_putpmsg = 182
|
||||
const SYS_afs_syscall = 183
|
||||
const SYS_tuxcall = 184
|
||||
const SYS_security = 185
|
||||
const SYS_gettid = 186
|
||||
const SYS_readahead = 187
|
||||
const SYS_setxattr = 188
|
||||
const SYS_lsetxattr = 189
|
||||
const SYS_fsetxattr = 190
|
||||
const SYS_getxattr = 191
|
||||
const SYS_lgetxattr = 192
|
||||
const SYS_fgetxattr = 193
|
||||
const SYS_listxattr = 194
|
||||
const SYS_llistxattr = 195
|
||||
const SYS_flistxattr = 196
|
||||
const SYS_removexattr = 197
|
||||
const SYS_lremovexattr = 198
|
||||
const SYS_fremovexattr = 199
|
||||
const SYS_tkill = 200
|
||||
const SYS_time = 201
|
||||
const SYS_futex = 202
|
||||
const SYS_sched_setaffinity = 203
|
||||
const SYS_sched_getaffinity = 204
|
||||
const SYS_set_thread_area = 205
|
||||
const SYS_io_setup = 206
|
||||
const SYS_io_destroy = 207
|
||||
const SYS_io_getevents = 208
|
||||
const SYS_io_submit = 209
|
||||
const SYS_io_cancel = 210
|
||||
const SYS_get_thread_area = 211
|
||||
const SYS_lookup_dcookie = 212
|
||||
const SYS_epoll_create = 213
|
||||
const SYS_epoll_ctl_old = 214
|
||||
const SYS_epoll_wait_old = 215
|
||||
const SYS_remap_file_pages = 216
|
||||
const SYS_getdents64 = 217
|
||||
const SYS_set_tid_address = 218
|
||||
const SYS_restart_syscall = 219
|
||||
const SYS_semtimedop = 220
|
||||
const SYS_fadvise64 = 221
|
||||
const SYS_timer_create = 222
|
||||
const SYS_timer_settime = 223
|
||||
const SYS_timer_gettime = 224
|
||||
const SYS_timer_getoverrun = 225
|
||||
const SYS_timer_delete = 226
|
||||
const SYS_clock_settime = 227
|
||||
const SYS_clock_gettime = 228
|
||||
const SYS_clock_getres = 229
|
||||
const SYS_clock_nanosleep = 230
|
||||
const SYS_exit_group = 231
|
||||
const SYS_epoll_wait = 232
|
||||
const SYS_epoll_ctl = 233
|
||||
const SYS_tgkill = 234
|
||||
const SYS_utimes = 235
|
||||
const SYS_vserver = 236
|
||||
const SYS_mbind = 237
|
||||
const SYS_set_mempolicy = 238
|
||||
const SYS_get_mempolicy = 239
|
||||
const SYS_mq_open = 240
|
||||
const SYS_mq_unlink = 241
|
||||
const SYS_mq_timedsend = 242
|
||||
const SYS_mq_timedreceive = 243
|
||||
const SYS_mq_notify = 244
|
||||
const SYS_mq_getsetattr = 245
|
||||
const SYS_kexec_load = 246
|
||||
const SYS_waitid = 247
|
||||
const SYS_add_key = 248
|
||||
const SYS_request_key = 249
|
||||
const SYS_keyctl = 250
|
||||
const SYS_ioprio_set = 251
|
||||
const SYS_ioprio_get = 252
|
||||
const SYS_inotify_init = 253
|
||||
const SYS_inotify_add_watch = 254
|
||||
const SYS_inotify_rm_watch = 255
|
||||
const SYS_migrate_pages = 256
|
||||
const SYS_openat = 257
|
||||
const SYS_mkdirat = 258
|
||||
const SYS_mknodat = 259
|
||||
const SYS_fchownat = 260
|
||||
const SYS_futimesat = 261
|
||||
const SYS_newfstatat = 262
|
||||
const SYS_unlinkat = 263
|
||||
const SYS_renameat = 264
|
||||
const SYS_linkat = 265
|
||||
const SYS_symlinkat = 266
|
||||
const SYS_readlinkat = 267
|
||||
const SYS_fchmodat = 268
|
||||
const SYS_faccessat = 269
|
||||
const SYS_pselect6 = 270
|
||||
const SYS_ppoll = 271
|
||||
const SYS_unshare = 272
|
||||
const SYS_set_robust_list = 273
|
||||
const SYS_get_robust_list = 274
|
||||
const SYS_splice = 275
|
||||
const SYS_tee = 276
|
||||
const SYS_sync_file_range = 277
|
||||
const SYS_vmsplice = 278
|
||||
const SYS_move_pages = 279
|
||||
const SYS_utimensat = 280
|
||||
const SYS_epoll_pwait = 281
|
||||
const SYS_signalfd = 282
|
||||
const SYS_timerfd_create = 283
|
||||
const SYS_eventfd = 284
|
||||
const SYS_fallocate = 285
|
||||
const SYS_timerfd_settime = 286
|
||||
const SYS_timerfd_gettime = 287
|
||||
const SYS_accept4 = 288
|
||||
const SYS_signalfd4 = 289
|
||||
const SYS_eventfd2 = 290
|
||||
const SYS_epoll_create1 = 291
|
||||
const SYS_dup3 = 292
|
||||
const SYS_pipe2 = 293
|
||||
const SYS_inotify_init1 = 294
|
||||
const SYS_preadv = 295
|
||||
const SYS_pwritev = 296
|
||||
const SYS_rt_tgsigqueueinfo = 297
|
||||
const SYS_perf_event_open = 298
|
||||
const SYS_recvmmsg = 299
|
||||
const SYS_fanotify_init = 300
|
||||
const SYS_fanotify_mark = 301
|
||||
const SYS_prlimit64 = 302
|
||||
const SYS_name_to_handle_at = 303
|
||||
const SYS_open_by_handle_at = 304
|
||||
const SYS_clock_adjtime = 305
|
||||
const SYS_syncfs = 306
|
||||
const SYS_sendmmsg = 307
|
||||
const SYS_setns = 308
|
||||
const SYS_getcpu = 309
|
||||
const SYS_process_vm_readv = 310
|
||||
const SYS_process_vm_writev = 311
|
||||
const SYS_kcmp = 312
|
||||
const SYS_finit_module = 313
|
||||
const SYS_sched_setattr = 314
|
||||
const SYS_sched_getattr = 315
|
||||
const SYS_renameat2 = 316
|
||||
const SYS_seccomp = 317
|
||||
const SYS_getrandom = 318
|
||||
const SYS_memfd_create = 319
|
||||
const SYS_kexec_file_load = 320
|
||||
const SYS_bpf = 321
|
||||
const SYS_execveat = 322
|
||||
const SYS_userfaultfd = 323
|
||||
const SYS_membarrier = 324
|
||||
const SYS_mlock2 = 325
|
||||
const SYS_copy_file_range = 326
|
||||
const SYS_preadv2 = 327
|
||||
const SYS_pwritev2 = 328
|
||||
const SYS_pkey_mprotect = 329
|
||||
const SYS_pkey_alloc = 330
|
||||
const SYS_pkey_free = 331
|
||||
const SYS_statx = 332
|
||||
const SYS_io_pgetevents = 333
|
||||
const SYS_rseq = 334
|
||||
const SYS_uretprobe = 335
|
||||
const SYS_pidfd_send_signal = 424
|
||||
const SYS_io_uring_setup = 425
|
||||
const SYS_io_uring_enter = 426
|
||||
const SYS_io_uring_register = 427
|
||||
const SYS_open_tree = 428
|
||||
const SYS_move_mount = 429
|
||||
const SYS_fsopen = 430
|
||||
const SYS_fsconfig = 431
|
||||
const SYS_fsmount = 432
|
||||
const SYS_fspick = 433
|
||||
const SYS_pidfd_open = 434
|
||||
const SYS_clone3 = 435
|
||||
const SYS_close_range = 436
|
||||
const SYS_openat2 = 437
|
||||
const SYS_pidfd_getfd = 438
|
||||
const SYS_faccessat2 = 439
|
||||
const SYS_process_madvise = 440
|
||||
const SYS_epoll_pwait2 = 441
|
||||
const SYS_mount_setattr = 442
|
||||
const SYS_quotactl_fd = 443
|
||||
const SYS_landlock_create_ruleset = 444
|
||||
const SYS_landlock_add_rule = 445
|
||||
const SYS_landlock_restrict_self = 446
|
||||
const SYS_memfd_secret = 447
|
||||
const SYS_process_mrelease = 448
|
||||
const SYS_futex_waitv = 449
|
||||
const SYS_set_mempolicy_home_node = 450
|
||||
const SYS_cachestat = 451
|
||||
const SYS_fchmodat2 = 452
|
||||
const SYS_map_shadow_stack = 453
|
||||
const SYS_futex_wake = 454
|
||||
const SYS_futex_wait = 455
|
||||
const SYS_futex_requeue = 456
|
||||
const SYS_statmount = 457
|
||||
const SYS_listmount = 458
|
||||
const SYS_lsm_get_self_attr = 459
|
||||
const SYS_lsm_set_self_attr = 460
|
||||
const SYS_lsm_list_modules = 461
|
||||
const SYS_mseal = 462
|
||||
const SYS_setxattrat = 463
|
||||
const SYS_getxattrat = 464
|
||||
const SYS_listxattrat = 465
|
||||
const SYS_removexattrat = 466
|
||||
const SYS_open_tree_attr = 467
|
||||
236
src/std/net.zr
236
src/std/net.zr
@@ -1,236 +0,0 @@
|
||||
const AF_INET = 2
|
||||
const SOCK_STREAM = 1
|
||||
const SOCK_DGRAM = 2
|
||||
const SOL_SOCKET = 1
|
||||
const SO_REUSEADDR = 2
|
||||
const SOMAXCONN = 128
|
||||
const IP_MAXPACKET = 65535
|
||||
|
||||
const DNS_TYPE_A = 1
|
||||
const DNS_CLASS_IN = 1
|
||||
const DNS_RECURSION_DESIRED = 256
|
||||
|
||||
func net.listen[host: str, port: i64] : i64, bool
|
||||
s := _builtin_syscall(SYS_socket, AF_INET, SOCK_STREAM, 0)
|
||||
if s < 0
|
||||
return -1, false
|
||||
|
||||
optval := 1
|
||||
if _builtin_syscall(SYS_setsockopt, s, SOL_SOCKET, SO_REUSEADDR, ^optval, 8) < 0
|
||||
_builtin_syscall(SYS_close, s)
|
||||
return -1, false
|
||||
|
||||
~packed_host, ok := net.resolve(host)
|
||||
if !ok
|
||||
return -1, false
|
||||
|
||||
sa := _stackalloc(16)
|
||||
net._build_sa(sa, packed_host, port)
|
||||
|
||||
if _builtin_syscall(SYS_bind, s, sa, 16) < 0
|
||||
_builtin_syscall(SYS_close, s)
|
||||
return -1, false
|
||||
|
||||
if _builtin_syscall(SYS_listen, s, SOMAXCONN) < 0
|
||||
_builtin_syscall(SYS_close, s)
|
||||
return -1, false
|
||||
|
||||
return s, true
|
||||
|
||||
func net.connect[host: str, port: i64] : i64, bool
|
||||
s := _builtin_syscall(SYS_socket, AF_INET, SOCK_STREAM, 0)
|
||||
if s < 0
|
||||
return -1, false
|
||||
|
||||
~packed_host, ok := net.resolve(host)
|
||||
if !ok
|
||||
return -1, false
|
||||
|
||||
sa := _stackalloc(16)
|
||||
net._build_sa(sa, packed_host, port)
|
||||
|
||||
if _builtin_syscall(SYS_connect, s, sa, 16) < 0
|
||||
_builtin_syscall(SYS_close, s)
|
||||
return -1, false
|
||||
|
||||
return s, true
|
||||
|
||||
func net.accept[s: i64, addr: ptr] : i64
|
||||
addrlen := 16
|
||||
return _builtin_syscall(SYS_accept, s, addr, ^addrlen)
|
||||
|
||||
func net.send[s: i64, data: ptr, size: i64] : void
|
||||
_builtin_syscall(SYS_sendto, s, data, size, 0, 0, 0)
|
||||
|
||||
func net.read[s: i64, buffer: ptr, size: i64] : i64
|
||||
return _builtin_syscall(SYS_read, s, buffer, size)
|
||||
|
||||
func net.close[s: i64] : void
|
||||
_builtin_syscall(SYS_close, s)
|
||||
|
||||
func net.pack_addr[a: i64, b: i64, c: i64, d: i64] : i64
|
||||
return (a << 24) | (b << 16) | (c << 8) | d
|
||||
|
||||
func net._build_sa[sa: ptr, packed_host: i64, port: i64] : void
|
||||
mem.zero(sa, 16)
|
||||
sa[0] = AF_INET
|
||||
sa[1] = 0
|
||||
sa[2] = (port >> 8) & 255
|
||||
sa[3] = port & 255
|
||||
sa[4] = (packed_host >> 24) & 255
|
||||
sa[5] = (packed_host >> 16) & 255
|
||||
sa[6] = (packed_host >> 8) & 255
|
||||
sa[7] = packed_host & 255
|
||||
|
||||
struct net.UDPSocket
|
||||
fd: i64
|
||||
addr: ptr
|
||||
|
||||
func net.UDPSocket.receive[s: net.UDPSocket, size: i64] : net.UDPPacket
|
||||
pkt := new* net.UDPPacket
|
||||
pkt->data = mem.alloc(size)
|
||||
pkt->source_addr = mem.alloc(16)
|
||||
mem.zero(pkt->source_addr, 16)
|
||||
|
||||
addrlen := 16
|
||||
pkt->size = _builtin_syscall(SYS_recvfrom, s->fd, pkt->data, size, 0, pkt->source_addr, ^addrlen)
|
||||
return pkt
|
||||
|
||||
func net.UDPSocket.close_and_free[s: net.UDPSocket] : void
|
||||
_builtin_syscall(SYS_close, s->fd)
|
||||
s->addr->free()
|
||||
mem.free(s)
|
||||
|
||||
func net.create_udp_client[host: str, port: i64] : net.UDPSocket, bool
|
||||
s := new* net.UDPSocket
|
||||
|
||||
~packed_host, ok := net.resolve(host)
|
||||
if !ok
|
||||
return 0 as net.UDPSocket, false
|
||||
|
||||
s->fd = _builtin_syscall(SYS_socket, AF_INET, SOCK_DGRAM, 0)
|
||||
if s->fd < 0
|
||||
mem.free(s)
|
||||
return 0 as net.UDPSocket, false
|
||||
|
||||
s->addr = mem.alloc(16)
|
||||
net._build_sa(s->addr, packed_host, port)
|
||||
return s, true
|
||||
|
||||
func net.create_udp_server[host: str, port: i64] : net.UDPSocket, bool
|
||||
~s, ok := net.create_udp_client(host, port)
|
||||
if !ok
|
||||
return 0 as net.UDPSocket, false
|
||||
|
||||
if _builtin_syscall(SYS_bind, s->fd, s->addr, 16) < 0
|
||||
s->close_and_free()
|
||||
return 0 as net.UDPSocket, false
|
||||
|
||||
return s, true
|
||||
|
||||
func net.UDPSocket.send_to[s: net.UDPSocket, addr: ptr, data: ptr, size: i64] : void
|
||||
_builtin_syscall(SYS_sendto, s->fd, data, size, 0, addr, 16)
|
||||
|
||||
struct net.UDPPacket
|
||||
data: ptr
|
||||
source_addr: ptr
|
||||
size: i64
|
||||
|
||||
func net.UDPPacket.free[pkt: net.UDPPacket] : void
|
||||
pkt->data->free()
|
||||
pkt->source_addr->free()
|
||||
mem.free(pkt)
|
||||
|
||||
func net.resolve[domain: str] : i64, bool
|
||||
// if domain is already an ip, skip dns resolution
|
||||
parts := domain->split(".")
|
||||
if parts->size == 4
|
||||
valid := true
|
||||
for i in 0..4
|
||||
p := parts->nth(i) as str
|
||||
if p->len() < 1 || p->len() > 3
|
||||
valid = false
|
||||
break
|
||||
for j in 0..p->len()
|
||||
if !p[j]->is_digit()
|
||||
valid = false
|
||||
break
|
||||
if !valid
|
||||
break
|
||||
if valid
|
||||
a := (parts->nth(0) as str)->parse_i64()
|
||||
b := (parts->nth(1) as str)->parse_i64()
|
||||
c := (parts->nth(2) as str)->parse_i64()
|
||||
d := (parts->nth(3) as str)->parse_i64()
|
||||
if a >= 0 && a <= 255 && b >= 0 && b <= 255 && c >= 0 && c <= 255 && d >= 0 && d <= 255
|
||||
parts->free_with_items()
|
||||
return net.pack_addr(a, b, c, d), true
|
||||
parts->free_with_items()
|
||||
|
||||
query := net.build_dns_query(domain, DNS_TYPE_A)
|
||||
|
||||
// TODO: this probably shouldnt be hardcoded
|
||||
~s, ok := net.create_udp_client("1.1.1.1", 53)
|
||||
if !ok
|
||||
query->free()
|
||||
return -1, false
|
||||
|
||||
s->send_to(s->addr, query->data, query->size)
|
||||
query->free()
|
||||
pkt := s->receive(1024)
|
||||
s->close_and_free()
|
||||
|
||||
// TODO: do actual parsing
|
||||
|
||||
pos := 12 // skip header (12 bytes)
|
||||
|
||||
while pkt->data[pos] != 0
|
||||
pos += pkt->data[pos] + 1 // skip question
|
||||
|
||||
pos += 5 // skip null byte, type(2), class(2)
|
||||
|
||||
pos += 12 // skip name(2), type(2), class(2), ttl(4), rdlength(2)
|
||||
|
||||
out := net.pack_addr(pkt->data[pos] as i64, pkt->data[pos+1] as i64, pkt->data[pos+2] as i64, pkt->data[pos+3] as i64)
|
||||
pkt->free()
|
||||
return out, true
|
||||
|
||||
func net.encode_dns_name[domain: str] : Blob
|
||||
domain_len := domain->len()
|
||||
buf := Blob.alloc(domain_len + 2)
|
||||
out_pos := 0
|
||||
part_start := 0
|
||||
i := 0
|
||||
while i <= domain_len
|
||||
if i == domain_len || domain[i] == '.'
|
||||
part_len := i - part_start
|
||||
buf->data[out_pos] = part_len & 0xff
|
||||
out_pos += 1
|
||||
mem.copy(domain as ptr + part_start, buf->data + out_pos, part_len)
|
||||
out_pos += part_len
|
||||
part_start = i + 1
|
||||
i += 1
|
||||
|
||||
buf->data[out_pos] = 0
|
||||
return buf
|
||||
|
||||
func net.build_dns_query[domain_name: str, record_type: i64] : Blob
|
||||
name := net.encode_dns_name(domain_name)
|
||||
out := Blob.alloc(12 + name->size + 4)
|
||||
|
||||
// header
|
||||
id := (os.urandom_i64() % 65536)->abs()
|
||||
mem.write16be(out->data + 0, id)
|
||||
mem.write16be(out->data + 2, DNS_RECURSION_DESIRED)
|
||||
mem.write16be(out->data + 4, 1) // num_questions
|
||||
mem.write16be(out->data + 6, 0) // num_answers
|
||||
mem.write16be(out->data + 8, 0) // num_authorities
|
||||
mem.write16be(out->data + 10, 0) // num_additionals
|
||||
|
||||
// question
|
||||
mem.copy(name->data, out->data + 12, name->size)
|
||||
mem.write16be(out->data + 12 + name->size, record_type)
|
||||
mem.write16be(out->data + 12 + name->size + 2, DNS_CLASS_IN)
|
||||
|
||||
name->free()
|
||||
return out
|
||||
1242
src/std/std.zr
1242
src/std/std.zr
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,4 @@
|
||||
use std::{cmp::Ordering, fmt};
|
||||
use std::{cmp::Ordering, fmt, fs, path::Path};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum TokenType {
|
||||
@@ -378,6 +378,11 @@ impl Tokenizer {
|
||||
}
|
||||
|
||||
let lexeme: String = self.source[self.start..self.current].iter().collect();
|
||||
|
||||
if lexeme == "include" {
|
||||
return self.scan_include();
|
||||
}
|
||||
|
||||
self.add_token(match lexeme.as_str() {
|
||||
"const" => TokenType::KeywordConst,
|
||||
"if" => TokenType::KeywordIf,
|
||||
@@ -401,6 +406,49 @@ impl Tokenizer {
|
||||
})
|
||||
}
|
||||
|
||||
fn scan_include(&mut self) -> Result<(), ZernError> {
|
||||
if !self.match_char(' ') {
|
||||
return error!(self.loc, "expected a space after 'include'");
|
||||
}
|
||||
|
||||
if self.peek() != '"' {
|
||||
return error!(self.loc, "expected '#' after 'include '");
|
||||
}
|
||||
self.advance();
|
||||
|
||||
let path_start = self.current;
|
||||
while !self.eof() && self.peek() != '"' {
|
||||
self.advance();
|
||||
}
|
||||
|
||||
if self.eof() {
|
||||
return error!(self.loc, "unterminated string after 'include'");
|
||||
}
|
||||
|
||||
let path: String = self.source[path_start..self.current].iter().collect();
|
||||
self.advance(); // consume closing quote
|
||||
|
||||
self.include_file(path)
|
||||
}
|
||||
|
||||
// TODO: circular includes lead to "fatal runtime error: stack overflow, aborting"
|
||||
pub fn include_file(&mut self, path: String) -> Result<(), ZernError> {
|
||||
let source = match fs::read_to_string(&path) {
|
||||
Ok(x) => x,
|
||||
Err(_) => {
|
||||
return error!(self.loc, format!("failed to include {}", path));
|
||||
}
|
||||
};
|
||||
|
||||
let filename = Path::new(&path).file_name().unwrap().to_str().unwrap();
|
||||
|
||||
let tokenizer = Tokenizer::new(filename.to_owned(), source);
|
||||
self.tokens.extend(tokenizer.tokenize()?);
|
||||
self.tokens.pop(); // remove inner Eof
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn match_char(&mut self, expected: char) -> bool {
|
||||
if self.eof() || self.peek() != expected {
|
||||
false
|
||||
|
||||
Reference in New Issue
Block a user