Implemented boolean literals

This commit is contained in:
Eduard Urbach 2025-02-26 14:33:41 +01:00
parent 91f34bc88f
commit 5f46a6f14e
Signed by: akyoto
GPG Key ID: C874F672B1AF20C0
11 changed files with 69 additions and 13 deletions

View File

@ -9,7 +9,7 @@ main() {
return
}
if isPrime(i) == 1 {
if isPrime(i) {
if i != 2 {
io.out(" ")
}
@ -23,22 +23,22 @@ main() {
isPrime(x int) -> bool {
if x == 2 {
return 1
return true
}
if x % 2 == 0 {
return 0
return false
}
i := 3
loop {
if i * i > x {
return 1
return true
}
if x % i == 0 {
return 0
return false
}
i += 2

View File

@ -1,5 +1,5 @@
import sys
free(address []any) -> int {
return sys.munmap(address-8, len(address)+8)
free(address []any) {
sys.munmap(address-8, len(address)+8)
}

View File

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

View File

@ -1,8 +1,11 @@
package core
import (
"git.urbach.dev/cli/q/src/asm"
"git.urbach.dev/cli/q/src/errors"
"git.urbach.dev/cli/q/src/expression"
"git.urbach.dev/cli/q/src/token"
"git.urbach.dev/cli/q/src/types"
)
// CompileCondition inserts code to jump to the start label or end label depending on the truth of the condition.
@ -62,7 +65,26 @@ func (f *Function) CompileCondition(condition *expression.Expression, successLab
return err
default:
case token.Call:
typ, err := f.CompileCall(condition)
if err != nil {
return err
}
if len(typ) == 0 {
return errors.New(errors.UntypedExpression, f.File, condition.Token.Position)
}
if !types.Is(typ[0], types.Bool) {
return errors.New(&errors.TypeMismatch{Encountered: typ[0].Name(), Expected: types.Bool.Name()}, f.File, condition.Token.Position)
}
f.RegisterNumber(asm.COMPARE, f.CPU.Output[0], 0)
f.Jump(asm.JE, failLabel)
return nil
case token.Equal, token.NotEqual, token.Greater, token.Less, token.GreaterEqual, token.LessEqual:
err := f.Compare(condition)
if condition.Parent == nil {
@ -70,5 +92,8 @@ func (f *Function) CompileCondition(condition *expression.Expression, successLab
}
return err
default:
return errors.New(errors.InvalidCondition, f.File, condition.Token.Position)
}
}

View File

@ -1,6 +1,7 @@
package core
import (
"git.urbach.dev/cli/q/src/ast"
"git.urbach.dev/cli/q/src/cpu"
"git.urbach.dev/cli/q/src/errors"
"git.urbach.dev/cli/q/src/expression"
@ -24,6 +25,16 @@ func (f *Function) Evaluate(expr *expression.Expression) (types.Type, cpu.Regist
}
}
if ast.IsFunctionCall(expr) {
types, err := f.CompileCall(expr)
if err != nil {
return nil, 0, false, err
}
return types[0], f.CPU.Output[0], false, nil
}
tmp := f.NewRegister()
typ, err := f.ExpressionToRegister(expr, tmp)
return typ, tmp, true, err

View File

@ -16,6 +16,17 @@ func (f *Function) TokenToRegister(t token.Token, register cpu.Register) (types.
switch t.Kind {
case token.Identifier:
name := t.Text(f.File.Bytes)
if name == "true" {
f.RegisterNumber(asm.MOVE, register, 1)
return types.Bool, nil
}
if name == "false" {
f.RegisterNumber(asm.MOVE, register, 0)
return types.Bool, nil
}
variable, function := f.Identifier(name)
if variable != nil {

View File

@ -10,6 +10,7 @@ var (
ExpectedStructName = &Base{"Expected struct name"}
ExpectedDLLName = &Base{"Expected DLL name"}
InvalidNumber = &Base{"Invalid number"}
InvalidCondition = &Base{"Invalid condition"}
InvalidExpression = &Base{"Invalid expression"}
InvalidRune = &Base{"Invalid rune"}
MissingBlockStart = &Base{"Missing '{'"}

View File

@ -4,6 +4,7 @@ var (
Any = &Base{name: "any", size: 0}
AnyArray = &Array{Of: Any}
AnyPointer = &Pointer{To: Any}
Bool = &Base{name: "bool", size: 1}
Int64 = &Base{name: "int64", size: 8}
Int32 = &Base{name: "int32", size: 4}
Int16 = &Base{name: "int16", size: 2}
@ -14,7 +15,6 @@ var (
)
var (
Bool = Int
Byte = UInt8
Int = Int64
Float = Float64

View File

@ -25,8 +25,12 @@ func Is(a Type, b Type) bool {
return true
}
// Temporary hack for implicit casts
if a.Size() > b.Size() {
// Temporary hacks
if a == Int32 && b == Int64 {
return true
}
if a == Int64 && b == Int32 {
return true
}

View File

@ -0,0 +1,3 @@
main() {
if 42 {}
}

View File

@ -22,6 +22,7 @@ var errs = []struct {
{"ExpectedIfBeforeElse2.q", errors.ExpectedIfBeforeElse},
{"ExpectedStructName.q", errors.ExpectedStructName},
{"ExpectedPackageName.q", errors.ExpectedPackageName},
{"InvalidCondition.q", errors.InvalidCondition},
{"InvalidInstructionCall.q", &errors.InvalidInstruction{Instruction: "sys.write"}},
{"InvalidInstructionExpression.q", &errors.InvalidInstruction{Instruction: "2+3"}},
{"InvalidInstructionIdentifier.q", &errors.InvalidInstruction{Instruction: "abc"}},