Implemented boolean literals

This commit is contained in:
2025-02-26 14:33:41 +01:00
parent 91f34bc88f
commit 5f46a6f14e
11 changed files with 69 additions and 13 deletions

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
}