Improved file structure
This commit is contained in:
parent
453b4d8956
commit
42a212a3f4
17
src/arch/arm64/Syscall.go
Normal file
17
src/arch/arm64/Syscall.go
Normal file
@ -0,0 +1,17 @@
|
||||
package register
|
||||
|
||||
import "git.akyoto.dev/cli/q/src/register"
|
||||
|
||||
const (
|
||||
SyscallNumber = register.R8
|
||||
SyscallReturn = register.R0
|
||||
)
|
||||
|
||||
var SyscallArgs = []register.ID{
|
||||
register.R0,
|
||||
register.R1,
|
||||
register.R2,
|
||||
register.R3,
|
||||
register.R4,
|
||||
register.R5,
|
||||
}
|
22
src/arch/x64/Syscall.go
Normal file
22
src/arch/x64/Syscall.go
Normal file
@ -0,0 +1,22 @@
|
||||
package x64
|
||||
|
||||
import "git.akyoto.dev/cli/q/src/register"
|
||||
|
||||
const (
|
||||
SyscallNumber = register.R0 // rax
|
||||
SyscallReturn = register.R0 // rax
|
||||
)
|
||||
|
||||
var SyscallArgs = []register.ID{
|
||||
register.R7, // rdi
|
||||
register.R6, // rsi
|
||||
register.R2, // rdx
|
||||
register.R10,
|
||||
register.R8,
|
||||
register.R9,
|
||||
}
|
||||
|
||||
// Syscall is the primary way to communicate with the OS kernel.
|
||||
func Syscall(code []byte) []byte {
|
||||
return append(code, 0x0f, 0x05)
|
||||
}
|
16
src/arch/x64/x64_test.go
Normal file
16
src/arch/x64/x64_test.go
Normal file
@ -0,0 +1,16 @@
|
||||
package x64_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.akyoto.dev/cli/q/src/arch/x64"
|
||||
"git.akyoto.dev/go/assert"
|
||||
)
|
||||
|
||||
func TestX64(t *testing.T) {
|
||||
assert.DeepEqual(t, x64.Call([]byte{}, 1), []byte{0xe8, 0x01, 0x00, 0x00, 0x00})
|
||||
assert.DeepEqual(t, x64.MoveRegNum32([]byte{}, 0, 1), []byte{0xb8, 0x01, 0x00, 0x00, 0x00})
|
||||
assert.DeepEqual(t, x64.MoveRegNum32([]byte{}, 1, 1), []byte{0xb9, 0x01, 0x00, 0x00, 0x00})
|
||||
assert.DeepEqual(t, x64.Return([]byte{}), []byte{0xc3})
|
||||
assert.DeepEqual(t, x64.Syscall([]byte{}), []byte{0x0f, 0x05})
|
||||
}
|
@ -3,10 +3,10 @@ package asm
|
||||
import (
|
||||
"encoding/binary"
|
||||
|
||||
"git.akyoto.dev/cli/q/src/arch/x64"
|
||||
"git.akyoto.dev/cli/q/src/config"
|
||||
"git.akyoto.dev/cli/q/src/log"
|
||||
"git.akyoto.dev/cli/q/src/register"
|
||||
"git.akyoto.dev/cli/q/src/x64"
|
||||
)
|
||||
|
||||
// Assembler contains a list of instructions.
|
||||
|
@ -3,9 +3,9 @@ package asm_test
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.akyoto.dev/cli/q/src/arch/x64"
|
||||
"git.akyoto.dev/cli/q/src/asm"
|
||||
"git.akyoto.dev/cli/q/src/linux"
|
||||
"git.akyoto.dev/cli/q/src/register"
|
||||
"git.akyoto.dev/cli/q/src/os/linux"
|
||||
"git.akyoto.dev/go/assert"
|
||||
)
|
||||
|
||||
@ -13,14 +13,14 @@ func TestHello(t *testing.T) {
|
||||
a := asm.New()
|
||||
|
||||
hello := []byte("Hello\n")
|
||||
a.MoveRegisterNumber(register.Syscall0, linux.Write)
|
||||
a.MoveRegisterNumber(register.Syscall1, 1)
|
||||
a.MoveRegisterData(register.Syscall2, hello)
|
||||
a.MoveRegisterNumber(register.Syscall3, uint64(len(hello)))
|
||||
a.MoveRegisterNumber(x64.SyscallNumber, linux.Write)
|
||||
a.MoveRegisterNumber(x64.SyscallArgs[0], 1)
|
||||
a.MoveRegisterData(x64.SyscallArgs[1], hello)
|
||||
a.MoveRegisterNumber(x64.SyscallArgs[2], uint64(len(hello)))
|
||||
a.Syscall()
|
||||
|
||||
a.MoveRegisterNumber(register.Syscall0, linux.Exit)
|
||||
a.MoveRegisterNumber(register.Syscall1, 0)
|
||||
a.MoveRegisterNumber(x64.SyscallNumber, linux.Exit)
|
||||
a.MoveRegisterNumber(x64.SyscallArgs[0], 0)
|
||||
a.Syscall()
|
||||
|
||||
code, data := a.Finalize()
|
||||
|
@ -1,9 +1,9 @@
|
||||
package compiler
|
||||
|
||||
import (
|
||||
"git.akyoto.dev/cli/q/src/arch/x64"
|
||||
"git.akyoto.dev/cli/q/src/asm"
|
||||
"git.akyoto.dev/cli/q/src/linux"
|
||||
"git.akyoto.dev/cli/q/src/register"
|
||||
"git.akyoto.dev/cli/q/src/os/linux"
|
||||
)
|
||||
|
||||
// Finalize generates the final machine code.
|
||||
@ -14,8 +14,8 @@ func Finalize(functions map[string]*Function) ([]byte, []byte) {
|
||||
a.Merge(&f.Assembler)
|
||||
}
|
||||
|
||||
a.MoveRegisterNumber(register.Syscall0, linux.Exit)
|
||||
a.MoveRegisterNumber(register.Syscall1, 0)
|
||||
a.MoveRegisterNumber(x64.SyscallNumber, linux.Exit)
|
||||
a.MoveRegisterNumber(x64.SyscallArgs[0], 0)
|
||||
a.Syscall()
|
||||
|
||||
code, data := a.Finalize()
|
||||
|
@ -1,9 +1,9 @@
|
||||
package compiler
|
||||
|
||||
import (
|
||||
"git.akyoto.dev/cli/q/src/arch/x64"
|
||||
"git.akyoto.dev/cli/q/src/asm"
|
||||
"git.akyoto.dev/cli/q/src/linux"
|
||||
"git.akyoto.dev/cli/q/src/register"
|
||||
"git.akyoto.dev/cli/q/src/os/linux"
|
||||
"git.akyoto.dev/cli/q/src/token"
|
||||
)
|
||||
|
||||
@ -20,10 +20,10 @@ func (f *Function) Compile() {
|
||||
for i, t := range f.Body {
|
||||
if t.Kind == token.Identifier && t.String() == "print" {
|
||||
message := f.Body[i+2].Bytes
|
||||
f.Assembler.MoveRegisterNumber(register.Syscall0, linux.Write)
|
||||
f.Assembler.MoveRegisterNumber(register.Syscall1, 1)
|
||||
f.Assembler.MoveRegisterData(register.Syscall2, message)
|
||||
f.Assembler.MoveRegisterNumber(register.Syscall3, uint64(len(message)))
|
||||
f.Assembler.MoveRegisterNumber(x64.SyscallNumber, linux.Write)
|
||||
f.Assembler.MoveRegisterNumber(x64.SyscallArgs[0], 1)
|
||||
f.Assembler.MoveRegisterData(x64.SyscallArgs[1], message)
|
||||
f.Assembler.MoveRegisterNumber(x64.SyscallArgs[2], uint64(len(message)))
|
||||
f.Assembler.Syscall()
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +0,0 @@
|
||||
package keywords
|
||||
|
||||
// All defines the keywords used in the language.
|
||||
var All = map[string]bool{
|
||||
"return": true,
|
||||
}
|
@ -1,333 +0,0 @@
|
||||
package linux
|
||||
|
||||
const (
|
||||
Read = iota
|
||||
Write
|
||||
Open
|
||||
Close
|
||||
Stat
|
||||
Fstat
|
||||
Lstat
|
||||
Poll
|
||||
Lseek
|
||||
Mmap
|
||||
Mprotect
|
||||
Munmap
|
||||
Brk
|
||||
Rt_sigaction
|
||||
Rt_sigprocmask
|
||||
Rt_sigreturn
|
||||
Ioctl
|
||||
Pread64
|
||||
Pwrite64
|
||||
Readv
|
||||
Writev
|
||||
Access
|
||||
Pipe
|
||||
Select
|
||||
Sched_yield
|
||||
Mremap
|
||||
Msync
|
||||
Mincore
|
||||
Madvise
|
||||
Shmget
|
||||
Shmat
|
||||
Shmctl
|
||||
Dup
|
||||
Dup2
|
||||
Pause
|
||||
Nanosleep
|
||||
Getitimer
|
||||
Alarm
|
||||
Setitimer
|
||||
Getpid
|
||||
Sendfile
|
||||
Socket
|
||||
Connect
|
||||
Accept
|
||||
Sendto
|
||||
Recvfrom
|
||||
Sendmsg
|
||||
Recvmsg
|
||||
Shutdown
|
||||
Bind
|
||||
Listen
|
||||
Getsockname
|
||||
Getpeername
|
||||
Socketpair
|
||||
Setsockopt
|
||||
Getsockopt
|
||||
Clone
|
||||
Fork
|
||||
Vfork
|
||||
Execve
|
||||
Exit
|
||||
Wait4
|
||||
Kill
|
||||
Uname
|
||||
Semget
|
||||
Semop
|
||||
Semctl
|
||||
Shmdt
|
||||
Msgget
|
||||
Msgsnd
|
||||
Msgrcv
|
||||
Msgctl
|
||||
Fcntl
|
||||
Flock
|
||||
Fsync
|
||||
Fdatasync
|
||||
Truncate
|
||||
Ftruncate
|
||||
Getdents
|
||||
Getcwd
|
||||
Chdir
|
||||
Fchdir
|
||||
Rename
|
||||
Mkdir
|
||||
Rmdir
|
||||
Creat
|
||||
Link
|
||||
Unlink
|
||||
Symlink
|
||||
Readlink
|
||||
Chmod
|
||||
Fchmod
|
||||
Chown
|
||||
Fchown
|
||||
Lchown
|
||||
Umask
|
||||
Gettimeofday
|
||||
Getrlimit
|
||||
Getrusage
|
||||
Sysinfo
|
||||
Times
|
||||
Ptrace
|
||||
Getuid
|
||||
Syslog
|
||||
Getgid
|
||||
Setuid
|
||||
Setgid
|
||||
Geteuid
|
||||
Getegid
|
||||
Setpgid
|
||||
Getppid
|
||||
Getpgrp
|
||||
Setsid
|
||||
Setreuid
|
||||
Setregid
|
||||
Getgroups
|
||||
Setgroups
|
||||
Setresuid
|
||||
Getresuid
|
||||
Setresgid
|
||||
Getresgid
|
||||
Getpgid
|
||||
Setfsuid
|
||||
Setfsgid
|
||||
Getsid
|
||||
Capget
|
||||
Capset
|
||||
Rt_sigpending
|
||||
Rt_sigtimedwait
|
||||
Rt_sigqueueinfo
|
||||
Rt_sigsuspend
|
||||
Sigaltstack
|
||||
Utime
|
||||
Mknod
|
||||
Uselib
|
||||
Personality
|
||||
Ustat
|
||||
Statfs
|
||||
Fstatfs
|
||||
Sysfs
|
||||
Getpriority
|
||||
Setpriority
|
||||
Sched_setparam
|
||||
Sched_getparam
|
||||
Sched_setscheduler
|
||||
Sched_getscheduler
|
||||
Sched_get_priority_max
|
||||
Sched_get_priority_min
|
||||
Sched_rr_get_interval
|
||||
Mlock
|
||||
Munlock
|
||||
Mlockall
|
||||
Munlockall
|
||||
Vhangup
|
||||
Modify_ldt
|
||||
Pivot_root
|
||||
Sysctl
|
||||
Prctl
|
||||
Arch_prctl
|
||||
Adjtimex
|
||||
Setrlimit
|
||||
Chroot
|
||||
Sync
|
||||
Acct
|
||||
Settimeofday
|
||||
Mount
|
||||
Umount2
|
||||
Swapon
|
||||
Swapoff
|
||||
Reboot
|
||||
Sethostname
|
||||
Setdomainname
|
||||
Iopl
|
||||
Ioperm
|
||||
Create_module
|
||||
Init_module
|
||||
Delete_module
|
||||
Get_kernel_syms
|
||||
Query_module
|
||||
Quotactl
|
||||
Nfsservctl
|
||||
Getpmsg
|
||||
Putpmsg
|
||||
Afs_syscall
|
||||
Tuxcall
|
||||
Security
|
||||
Gettid
|
||||
Readahead
|
||||
Setxattr
|
||||
Lsetxattr
|
||||
Fsetxattr
|
||||
Getxattr
|
||||
Lgetxattr
|
||||
Fgetxattr
|
||||
Listxattr
|
||||
Llistxattr
|
||||
Flistxattr
|
||||
Removexattr
|
||||
Lremovexattr
|
||||
Fremovexattr
|
||||
Tkill
|
||||
Time
|
||||
Futex
|
||||
Sched_setaffinity
|
||||
Sched_getaffinity
|
||||
Set_thread_area
|
||||
Io_setup
|
||||
Io_destroy
|
||||
Io_getevents
|
||||
Io_submit
|
||||
Io_cancel
|
||||
Get_thread_area
|
||||
Lookup_dcookie
|
||||
Epoll_create
|
||||
Epoll_ctl_old
|
||||
Epoll_wait_old
|
||||
Remap_file_pages
|
||||
Getdents64
|
||||
Set_tid_address
|
||||
Restart_syscall
|
||||
Semtimedop
|
||||
Fadvise64
|
||||
Timer_create
|
||||
Timer_settime
|
||||
Timer_gettime
|
||||
Timer_getoverrun
|
||||
Timer_delete
|
||||
Clock_settime
|
||||
Clock_gettime
|
||||
Clock_getres
|
||||
Clock_nanosleep
|
||||
Exit_group
|
||||
Epoll_wait
|
||||
Epoll_ctl
|
||||
Tgkill
|
||||
Utimes
|
||||
Vserver
|
||||
Mbind
|
||||
Set_mempolicy
|
||||
Get_mempolicy
|
||||
Mq_open
|
||||
Mq_unlink
|
||||
Mq_timedsend
|
||||
Mq_timedreceive
|
||||
Mq_notify
|
||||
Mq_getsetattr
|
||||
Kexec_load
|
||||
Waitid
|
||||
Add_key
|
||||
Request_key
|
||||
Keyctl
|
||||
Ioprio_set
|
||||
Ioprio_get
|
||||
Inotify_init
|
||||
Inotify_add_watch
|
||||
Inotify_rm_watch
|
||||
Migrate_pages
|
||||
Openat
|
||||
Mkdirat
|
||||
Mknodat
|
||||
Fchownat
|
||||
Futimesat
|
||||
Newfstatat
|
||||
Unlinkat
|
||||
Renameat
|
||||
Linkat
|
||||
Symlinkat
|
||||
Readlinkat
|
||||
Fchmodat
|
||||
Faccessat
|
||||
Pselect6
|
||||
Ppoll
|
||||
Unshare
|
||||
Set_robust_list
|
||||
Get_robust_list
|
||||
Splice
|
||||
Tee
|
||||
Sync_file_range
|
||||
Vmsplice
|
||||
Move_pages
|
||||
Utimensat
|
||||
Epoll_pwait
|
||||
Signalfd
|
||||
Timerfd_create
|
||||
Eventfd
|
||||
Fallocate
|
||||
Timerfd_settime
|
||||
Timerfd_gettime
|
||||
Accept4
|
||||
Signalfd4
|
||||
Eventfd2
|
||||
Epoll_create1
|
||||
Dup3
|
||||
Pipe2
|
||||
Inotify_init1
|
||||
Preadv
|
||||
Pwritev
|
||||
Rt_tgsigqueueinfo
|
||||
Perf_event_open
|
||||
Recvmmsg
|
||||
Fanotify_init
|
||||
Fanotify_mark
|
||||
Prlimit64
|
||||
Name_to_handle_at
|
||||
Open_by_handle_at
|
||||
Clock_adjtime
|
||||
Syncfs
|
||||
Sendmmsg
|
||||
Setns
|
||||
Getcpu
|
||||
Process_vm_readv
|
||||
Process_vm_writev
|
||||
Kcmp
|
||||
Finit_module
|
||||
Sched_setattr
|
||||
Sched_getattr
|
||||
Renameat2
|
||||
Seccomp
|
||||
Getrandom
|
||||
Memfd_create
|
||||
Kexec_file_load
|
||||
Bpf
|
||||
Stub_execveat
|
||||
Userfaultfd
|
||||
Membarrier
|
||||
Mlock2
|
||||
Copy_file_range
|
||||
Preadv2
|
||||
Pwritev2
|
||||
)
|
10
src/os/linux/Syscall.go
Normal file
10
src/os/linux/Syscall.go
Normal file
@ -0,0 +1,10 @@
|
||||
package linux
|
||||
|
||||
// https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/x86/entry/syscalls/syscall_64.tbl
|
||||
const (
|
||||
Read = 0
|
||||
Write = 1
|
||||
Open = 2
|
||||
Close = 3
|
||||
Exit = 60
|
||||
)
|
@ -22,6 +22,21 @@ const (
|
||||
R13
|
||||
R14
|
||||
R15
|
||||
R16
|
||||
R17
|
||||
R18
|
||||
R19
|
||||
R20
|
||||
R21
|
||||
R22
|
||||
R23
|
||||
R24
|
||||
R25
|
||||
R26
|
||||
R27
|
||||
R28
|
||||
R29
|
||||
R30
|
||||
)
|
||||
|
||||
func (r ID) String() string {
|
||||
|
@ -1,11 +0,0 @@
|
||||
package register
|
||||
|
||||
const (
|
||||
Syscall0 = R0
|
||||
Syscall1 = R7
|
||||
Syscall2 = R6
|
||||
Syscall3 = R2
|
||||
Syscall4 = R10
|
||||
Syscall5 = R8
|
||||
Syscall6 = R9
|
||||
)
|
6
src/token/Keywords.go
Normal file
6
src/token/Keywords.go
Normal file
@ -0,0 +1,6 @@
|
||||
package token
|
||||
|
||||
// Keywords defines the keywords used in the language.
|
||||
var Keywords = map[string]bool{
|
||||
"return": true,
|
||||
}
|
@ -1,7 +1,5 @@
|
||||
package token
|
||||
|
||||
import "git.akyoto.dev/cli/q/src/keywords"
|
||||
|
||||
// Pre-allocate these byte buffers so we can re-use them
|
||||
// instead of allocating a new buffer every time.
|
||||
var (
|
||||
@ -87,7 +85,7 @@ func Tokenize(buffer []byte) List {
|
||||
buffer[position:i],
|
||||
}
|
||||
|
||||
if keywords.All[string(token.Bytes)] {
|
||||
if Keywords[string(token.Bytes)] {
|
||||
token.Kind = Keyword
|
||||
}
|
||||
|
||||
|
@ -1,6 +0,0 @@
|
||||
package x64
|
||||
|
||||
// Syscall is the primary way to communicate with the OS kernel.
|
||||
func Syscall(code []byte) []byte {
|
||||
return append(code, 0x0f, 0x05)
|
||||
}
|
Loading…
Reference in New Issue
Block a user