Implemented boolean literals
This commit is contained in:
parent
91f34bc88f
commit
5f46a6f14e
@ -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
|
||||
|
@ -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)
|
||||
}
|
@ -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)
|
||||
}
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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 '{'"}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
3
tests/errors/InvalidCondition.q
Normal file
3
tests/errors/InvalidCondition.q
Normal file
@ -0,0 +1,3 @@
|
||||
main() {
|
||||
if 42 {}
|
||||
}
|
@ -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"}},
|
||||
|
Loading…
x
Reference in New Issue
Block a user