Fixed incorrect const values

This commit is contained in:
Eduard Urbach 2025-02-21 13:47:56 +01:00
parent 04ece57b27
commit 1ca61190eb
Signed by: akyoto
GPG Key ID: C874F672B1AF20C0
22 changed files with 93 additions and 92 deletions

View File

@ -1,5 +1,5 @@
import io
import mem import mem
import sys
main() { main() {
length := 5 length := 5
@ -9,6 +9,6 @@ main() {
address[2] = 'l' address[2] = 'l'
address[3] = 'l' address[3] = 'l'
address[4] = 'o' address[4] = 'o'
sys.write(1, address, length) io.write(1, address)
mem.free(address) mem.free(address)
} }

View File

@ -8,7 +8,7 @@ number(x int) {
mem.free(buffer) mem.free(buffer)
} }
itoa(x int, buffer []byte) -> (*any, int) { itoa(x int, buffer []byte) -> (*byte, int) {
end := buffer + len(buffer) end := buffer + len(buffer)
tmp := end tmp := end
digit := 0 digit := 0

View File

@ -1,22 +0,0 @@
import sys
alloc(length int) -> []byte {
x := sys.mmap(0, length+8, prot.read|prot.write, map.private|map.anonymous)
if x < 0x1000 {
return x
}
store(x, 8, length)
return x + 8
}
const prot {
read 0x1
write 0x2
}
const map {
private 0x02
anonymous 0x1000
}

View File

@ -9,14 +9,4 @@ alloc(length int) -> []byte {
store(x, 8, length) store(x, 8, length)
return x + 8 return x + 8
}
const prot {
read 0x1
write 0x2
}
const map {
private 0x02
anonymous 0x20
} }

View File

@ -1,7 +1,9 @@
import sys extern kernel32 {
VirtualAlloc(address int, size uint, flags uint32, protection uint32) -> *any
}
alloc(length int) -> []byte { alloc(length int) -> []byte {
x := sys.mmap(0, length+8, page.readwrite, mem.commit|mem.reserve) x := kernel32.VirtualAlloc(0, length+8, mem.commit|mem.reserve, page.readwrite)
if x < 0x1000 { if x < 0x1000 {
return x return x
@ -9,13 +11,4 @@ alloc(length int) -> []byte {
store(x, 8, length) store(x, 8, length)
return x + 8 return x + 8
}
const page {
readwrite 0x0004
}
const mem {
commit 0x1000
reserve 0x2000
} }

9
lib/mem/const_linux.q Normal file
View File

@ -0,0 +1,9 @@
const prot {
read 0x1
write 0x2
}
const map {
private 0x02
anonymous 0x20
}

9
lib/mem/const_mac.q Normal file
View File

@ -0,0 +1,9 @@
const prot {
read 0x1
write 0x2
}
const map {
private 0x02
anonymous 0x1000
}

9
lib/mem/const_windows.q Normal file
View File

@ -0,0 +1,9 @@
const page {
readwrite 0x0004
}
const mem {
commit 0x1000
reserve 0x2000
decommit 0x4000
}

7
lib/mem/free_windows.q Normal file
View File

@ -0,0 +1,7 @@
extern kernel32 {
VirtualFree(address *any, size uint, type uint32) -> bool
}
free(address []any) -> int {
return kernel32.VirtualFree(address-8, len(address)+8, mem.decommit)
}

View File

@ -1,8 +1,8 @@
read(fd int, buffer *any, length int) -> int { read(fd int, buffer *byte, length int) -> int {
return syscall(0, fd, buffer, length) return syscall(0, fd, buffer, length)
} }
write(fd int, buffer *any, length int) -> int { write(fd int, buffer *byte, length int) -> int {
return syscall(1, fd, buffer, length) return syscall(1, fd, buffer, length)
} }
@ -14,16 +14,16 @@ close(fd int) -> int {
return syscall(3, fd) return syscall(3, fd)
} }
mmap(address int, length int, protection int, flags int) -> *any { mmap(address int, length uint, protection int, flags int) -> *any {
return syscall(9, address, length, protection, flags) return syscall(9, address, length, protection, flags)
} }
munmap(address *any, length int) -> int { munmap(address *any, length uint) -> int {
return syscall(11, address, length) return syscall(11, address, length)
} }
clone(flags int, stack *any) -> int { clone(flags uint, stack *any, parent *int, child *int, tls uint) -> int {
return syscall(56, flags, stack) return syscall(56, flags, stack, parent, child, tls)
} }
fork() -> int { fork() -> int {

View File

@ -1,8 +1,8 @@
read(fd int, buffer *any, length int) -> int { read(fd int, buffer *byte, length int) -> int {
return syscall(0x2000003, fd, buffer, length) return syscall(0x2000003, fd, buffer, length)
} }
write(fd int, buffer *any, length int) -> int { write(fd int, buffer *byte, length int) -> int {
return syscall(0x2000004, fd, buffer, length) return syscall(0x2000004, fd, buffer, length)
} }

View File

@ -1,31 +1,17 @@
read(fd int64, buffer *any, length int64) -> int64 { read(fd int64, buffer *byte, length int64) -> int64 {
fd = kernel32.GetStdHandle(-10 - fd) fd = kernel32.GetStdHandle(-10 - fd)
kernel32.ReadConsole(fd, buffer, length, 0) kernel32.ReadConsole(fd, buffer, length, 0)
return length return length
} }
write(fd int64, buffer *any, length int64) -> int64 { write(fd int64, buffer *byte, length int64) -> int64 {
fd = kernel32.GetStdHandle(-10 - fd) fd = kernel32.GetStdHandle(-10 - fd)
kernel32.WriteConsoleA(fd, buffer, length, 0) kernel32.WriteConsoleA(fd, buffer, length, 0)
return length return length
} }
mmap(address int, length int, protection int, flags int) -> *any {
return kernel32.VirtualAlloc(address, length, flags, protection)
}
munmap(address *any, length int) -> int {
return kernel32.VirtualFree(address, length, mem.decommit)
}
const mem {
decommit 0x4000
}
extern kernel32 { extern kernel32 {
GetStdHandle(handle int64) -> int64 GetStdHandle(handle int64) -> int64
ReadConsole(fd int64, buffer *any, length uint32, written *uint32) -> bool ReadConsole(fd int64, buffer *byte, length uint32, written *uint32) -> bool
VirtualAlloc(address int, length int, flags int, protection int) WriteConsoleA(fd int64, buffer *byte, length uint32, written *uint32) -> bool
VirtualFree(address *any, length int, type int) -> bool
WriteConsoleA(fd int64, buffer *any, length uint32, written *uint32) -> bool
} }

View File

@ -19,5 +19,5 @@ create(func *any) -> int {
store(stack, 8, core.exit) store(stack, 8, core.exit)
stack -= 8 stack -= 8
store(stack, 8, func) store(stack, 8, func)
return sys.clone(clone.vm|clone.fs|clone.files|clone.sighand|clone.parent|clone.thread|clone.io, stack) return sys.clone(clone.vm|clone.fs|clone.files|clone.sighand|clone.parent|clone.thread|clone.io, stack, 0, 0, 0)
} }

View File

@ -8,6 +8,6 @@ import (
// Constant registers a single value to be accessible under a descriptive name. // Constant registers a single value to be accessible under a descriptive name.
type Constant struct { type Constant struct {
Name string Name string
Value token.Token Token token.Token
File *fs.File File *fs.File
} }

View File

@ -64,14 +64,16 @@ func (f *Function) ExpressionToRegister(node *expression.Expression, register cp
f.FreeRegister(register) f.FreeRegister(register)
} }
_, isArray := typ.(*types.Array) arrayType, isArray := typ.(*types.Array)
if isArray { if isArray {
typ = types.AnyPointer typ = &types.Pointer{To: arrayType.Of}
} else if right.Token.Kind == token.Identifier { } else if right.Token.Kind == token.Identifier {
rightVariable := f.VariableByName(right.Token.Text(f.File.Bytes)) rightVariable := f.VariableByName(right.Token.Text(f.File.Bytes))
leftPointer, leftIsPointer := typ.(*types.Pointer)
rightPointer, rightIsPointer := rightVariable.Type.(*types.Pointer)
if typ == types.AnyPointer && rightVariable.Type == types.AnyPointer { if leftIsPointer && rightIsPointer && leftPointer.To == rightPointer.To {
typ = types.Int typ = types.Int
} }
} }

View File

@ -38,7 +38,7 @@ func (f *Function) Fold(expr *expression.Expression) error {
return nil return nil
} }
value, err := f.ToNumber(constant.Value) value, err := ToNumber(constant.Token, constant.File)
expr.Value = value expr.Value = value
expr.IsFolded = true expr.IsFolded = true
return err return err

View File

@ -36,7 +36,15 @@ func (f *Function) PeriodToRegister(node *expression.Expression, register cpu.Re
constant, isConst := f.Constants[f.Package+"."+leftText+"."+rightText] constant, isConst := f.Constants[f.Package+"."+leftText+"."+rightText]
if isConst { if isConst {
return f.TokenToRegister(constant.Value, register) number, err := ToNumber(constant.Token, constant.File)
if err != nil {
return nil, err
}
f.SaveRegister(register)
f.RegisterNumber(asm.MOVE, register, number)
return types.Int, nil
} }
uniqueName := fmt.Sprintf("%s.%s", leftText, rightText) uniqueName := fmt.Sprintf("%s.%s", leftText, rightText)

View File

@ -6,15 +6,21 @@ import (
"unicode/utf8" "unicode/utf8"
"git.akyoto.dev/cli/q/src/errors" "git.akyoto.dev/cli/q/src/errors"
"git.akyoto.dev/cli/q/src/fs"
"git.akyoto.dev/cli/q/src/token" "git.akyoto.dev/cli/q/src/token"
) )
// ToNumber tries to convert the token into a numeric value. // ToNumber tries to convert the token into a numeric value.
func (f *Function) ToNumber(t token.Token) (int, error) { func (f *Function) ToNumber(t token.Token) (int, error) {
return ToNumber(t, f.File)
}
// ToNumber tries to convert the token into a numeric value.
func ToNumber(t token.Token, file *fs.File) (int, error) {
switch t.Kind { switch t.Kind {
case token.Number: case token.Number:
var ( var (
digits = t.Text(f.File.Bytes) digits = t.Text(file.Bytes)
number int64 number int64
err error err error
) )
@ -31,27 +37,27 @@ func (f *Function) ToNumber(t token.Token) (int, error) {
} }
if err != nil { if err != nil {
return 0, errors.New(errors.InvalidNumber, f.File, t.Position) return 0, errors.New(errors.InvalidNumber, file, t.Position)
} }
return int(number), nil return int(number), nil
case token.Rune: case token.Rune:
r := t.Bytes(f.File.Bytes) r := t.Bytes(file.Bytes)
r = String(r) r = String(r)
if len(r) == 0 { if len(r) == 0 {
return 0, errors.New(errors.InvalidRune, f.File, t.Position+1) return 0, errors.New(errors.InvalidRune, file, t.Position+1)
} }
number, size := utf8.DecodeRune(r) number, size := utf8.DecodeRune(r)
if len(r) > size { if len(r) > size {
return 0, errors.New(errors.InvalidRune, f.File, t.Position+1) return 0, errors.New(errors.InvalidRune, file, t.Position+1)
} }
return int(number), nil return int(number), nil
} }
return 0, errors.New(errors.InvalidNumber, f.File, t.Position) return 0, errors.New(errors.InvalidNumber, file, t.Position)
} }

View File

@ -29,6 +29,10 @@ func (s *Scanner) queueDirectory(directory string, pkg string) {
return return
} }
if strings.HasSuffix(name, "_unix.q") && config.TargetOS != config.Linux && config.TargetOS != config.Mac {
return
}
if strings.HasSuffix(name, "_windows.q") && config.TargetOS != config.Windows { if strings.HasSuffix(name, "_windows.q") && config.TargetOS != config.Windows {
return return
} }

View File

@ -25,18 +25,18 @@ func (s *Scanner) scanConst(file *fs.File, tokens token.List, i int) (int, error
i++ i++
for i < len(tokens) { for i < len(tokens) {
if tokens[i].Kind == token.Identifier { switch tokens[i].Kind {
case token.Identifier:
name := tokens[i].Text(file.Bytes) name := tokens[i].Text(file.Bytes)
i++ i++
s.constants <- &core.Constant{ s.constants <- &core.Constant{
Name: file.Package + "." + groupName + "." + name, Name: file.Package + "." + groupName + "." + name,
Value: tokens[i], Token: tokens[i],
File: file, File: file,
} }
}
if tokens[i].Kind == token.BlockEnd { case token.BlockEnd:
return i, nil return i, nil
} }

View File

@ -24,7 +24,8 @@ func (s *Scanner) scanExtern(file *fs.File, tokens token.List, i int) (int, erro
i++ i++
for i < len(tokens) { for i < len(tokens) {
if tokens[i].Kind == token.Identifier { switch tokens[i].Kind {
case token.Identifier:
function, j, err := scanFunctionSignature(file, tokens, i, token.NewLine) function, j, err := scanFunctionSignature(file, tokens, i, token.NewLine)
if err != nil { if err != nil {
@ -35,9 +36,8 @@ func (s *Scanner) scanExtern(file *fs.File, tokens token.List, i int) (int, erro
function.Package = dllName function.Package = dllName
function.UniqueName = dllName + "." + function.Name function.UniqueName = dllName + "." + function.Name
s.functions <- function s.functions <- function
}
if tokens[i].Kind == token.BlockEnd { case token.BlockEnd:
return i, nil return i, nil
} }