Generator understands assigning return/break to things
This commit is contained in:
parent
ebc4aacf5b
commit
e889a9c49b
|
@ -49,6 +49,7 @@ func (this *generator) generateIfElse (ifelse *entity.IfElse, mode resultMode) (
|
|||
var trueBlock, falseBlock *llvm.Block
|
||||
var tru, fals llvm.Value
|
||||
var loc bool
|
||||
var irIncomings []*llvm.Incoming
|
||||
|
||||
trueBlock = this.blockManager.newBlock()
|
||||
exitBlock := this.blockManager.newBlock()
|
||||
|
@ -56,7 +57,15 @@ func (this *generator) generateIfElse (ifelse *entity.IfElse, mode resultMode) (
|
|||
|
||||
tru, loc, err = this.generateExpression(ifelse.True, mode)
|
||||
if err != nil { return nil, false, err }
|
||||
if !this.blockManager.Terminated() { this.blockManager.NewBr(exitBlock) }
|
||||
if !this.blockManager.Terminated() {
|
||||
if tru != nil {
|
||||
irIncomings = append(irIncomings, &llvm.Incoming {
|
||||
X: tru,
|
||||
Predecessor: this.blockManager.Block,
|
||||
})
|
||||
}
|
||||
this.blockManager.NewBr(exitBlock)
|
||||
}
|
||||
|
||||
if ifelse.False == nil {
|
||||
// there is no false case
|
||||
|
@ -66,9 +75,22 @@ func (this *generator) generateIfElse (ifelse *entity.IfElse, mode resultMode) (
|
|||
} else {
|
||||
// there is a false case
|
||||
falseBlock = this.blockManager.newBlock()
|
||||
fals, _, err = this.generateExpression(ifelse.False, mode)
|
||||
thisMode := mode
|
||||
if mode != resultModeAny {
|
||||
if loc { thisMode = resultModeLoc
|
||||
} else { thisMode = resultModeVal }
|
||||
}
|
||||
fals, _, err = this.generateExpression(ifelse.False, thisMode)
|
||||
if err != nil { return nil, false, err }
|
||||
if !this.blockManager.Terminated() { this.blockManager.NewBr(exitBlock) }
|
||||
if !this.blockManager.Terminated() {
|
||||
if fals != nil {
|
||||
irIncomings = append(irIncomings, &llvm.Incoming {
|
||||
X: fals,
|
||||
Predecessor: this.blockManager.Block,
|
||||
})
|
||||
}
|
||||
this.blockManager.NewBr(exitBlock)
|
||||
}
|
||||
|
||||
if mode == resultModeAny {
|
||||
// discard results of statements
|
||||
|
@ -78,18 +100,9 @@ func (this *generator) generateIfElse (ifelse *entity.IfElse, mode resultMode) (
|
|||
} else {
|
||||
// obtain results of statements
|
||||
// set up phi to capture results
|
||||
trueIncoming := &llvm.Incoming {
|
||||
X: tru,
|
||||
Predecessor: trueBlock,
|
||||
}
|
||||
falseIncoming := &llvm.Incoming {
|
||||
X: fals,
|
||||
Predecessor: falseBlock,
|
||||
}
|
||||
|
||||
previous.NewCondBr(condition, trueBlock, falseBlock)
|
||||
this.blockManager.Block = exitBlock
|
||||
return this.blockManager.NewPhi(trueIncoming, falseIncoming), loc, nil
|
||||
return this.blockManager.NewPhi(irIncomings...), loc, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -105,8 +118,8 @@ func (this *generator) generateMatch (match *entity.Match, mode resultMode) (llv
|
|||
exitBlock := this.blockManager.newBlock()
|
||||
irHashType := llvm.I64
|
||||
|
||||
irCases := make([]*llvm.Case, len(match.Cases))
|
||||
irIncomings := make([]*llvm.Incoming, len(match.Cases))
|
||||
irCases := make([]*llvm.Case, len(match.Cases))
|
||||
irIncomings := []*llvm.Incoming { }
|
||||
for index, cas := range match.Cases {
|
||||
// set up ir case
|
||||
caseBlock := this.blockManager.newBlock()
|
||||
|
@ -124,7 +137,7 @@ func (this *generator) generateMatch (match *entity.Match, mode resultMode) (llv
|
|||
this.blockManager.addDeclaration(cas.Declaration, data)
|
||||
|
||||
// generate case expression
|
||||
thisMode := mode // FIXME this logic isnt in if/else, why??
|
||||
thisMode := mode
|
||||
if index != 0 && mode != resultModeAny {
|
||||
if loc { thisMode = resultModeLoc
|
||||
} else { thisMode = resultModeVal }
|
||||
|
@ -132,11 +145,15 @@ func (this *generator) generateMatch (match *entity.Match, mode resultMode) (llv
|
|||
caseExpression, thisLoc, err := this.generateExpression(cas.Expression, thisMode)
|
||||
if err != nil { return nil, false, err }
|
||||
if index == 0 { loc = thisLoc }
|
||||
irIncomings[index] = &llvm.Incoming {
|
||||
X: caseExpression,
|
||||
Predecessor: caseBlock,
|
||||
if !this.blockManager.Terminated() {
|
||||
if caseExpression != nil {
|
||||
irIncomings = append(irIncomings, &llvm.Incoming {
|
||||
X: caseExpression,
|
||||
Predecessor: this.blockManager.Block,
|
||||
})
|
||||
}
|
||||
this.blockManager.NewBr(exitBlock)
|
||||
}
|
||||
if !this.blockManager.Terminated() { this.blockManager.NewBr(exitBlock) }
|
||||
}
|
||||
|
||||
// create switch branch
|
||||
|
|
Loading…
Reference in New Issue