add check for always true, and pretty warnings
This commit is contained in:
parent
c8660a6471
commit
0d66db35aa
2 changed files with 54 additions and 11 deletions
10
cli/main.go
10
cli/main.go
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue