add check for always true, and pretty warnings

This commit is contained in:
Neemek 2025-09-30 16:02:18 +02:00
parent c8660a6471
commit 0d66db35aa
Signed by: neemek
GPG key ID: 84FFE4D7D40AB25E
2 changed files with 54 additions and 11 deletions

View file

@ -138,11 +138,15 @@ func makeChunk(ctx *Context, fpath string, ignoreWarnings bool) (*core.Chunk, er
}
// if there were non-critical warnings, report them
if !ignoreWarnings && len(c.Warnings) != 0 {
if len(c.Warnings) != 0 {
for _, warning := range c.Warnings {
log.Println(warning.Format())
log.Println(warning.Format() + "\n")
}
if !ignoreWarnings {
return nil, errors.New("compiler reported warning(s) (run anyways with --ignore-warnings)")
} else {
log.Println("compiler reported warning(s), but running anyways")
}
log.Fatal("compiler reported warning(s) (ignore warnings with the --ignore-warnings option)")
}
return c.Chunk, nil

View file

@ -279,6 +279,24 @@ func (c *Compiler) compile(tree Node) error {
return c.error(fmt.Sprintf("conditional requires boolean; cannot use non-boolean type %s", sig), n.condition)
}
if c.isTreeConstant(n.condition) {
v, err := c.compute(n.condition)
if err != nil {
return err
}
if v.(*BoolValue).Boolean {
c.warn("condition is always true", n.condition)
return c.compile(n.do)
} else {
c.warn("condition is always false", n.condition)
if n.otherwise != nil {
return c.compile(n.otherwise)
}
return nil
}
}
// the stack should have whether the condition was truthful
err = c.compile(n.condition)
if err != nil {
@ -330,15 +348,34 @@ func (c *Compiler) compile(tree Node) error {
return c.error(fmt.Sprintf("cannot loop over value of type %s; requires boolean", sig), n.condition)
}
conditionPos := c.ip
err = c.compile(n.condition)
if err != nil {
return err
alwaysLoop := false
if c.isTreeConstant(n.condition) {
v, err := c.compute(n.condition)
if err != nil {
return err
}
if !v.(*BoolValue).Boolean {
c.warn("while-loop condition is always false", n.condition)
return nil
} else {
c.warn("while-loop condition is always true", n.condition)
alwaysLoop = true
}
}
c.add(InstructionJumpFalse)
jumpValuePos := c.ip
c.advance(2)
conditionPos := c.ip
jumpValuePos := Pos(0)
if !alwaysLoop {
err = c.compile(n.condition)
if err != nil {
return err
}
c.add(InstructionJumpFalse)
jumpValuePos = c.ip
c.advance(2)
}
err = c.compile(n.do)
if err != nil {
@ -349,7 +386,9 @@ func (c *Compiler) compile(tree Node) error {
// condition pos < ip
c.addU16(uint16(c.ip - conditionPos + 2))
c.putU16(jumpValuePos, uint16(c.ip-jumpValuePos-2))
if !alwaysLoop {
c.putU16(jumpValuePos, uint16(c.ip-jumpValuePos-2))
}
case AssignNodeType:
n := tree.(*AssignNode)