PS: Implement _just enough_ control flow to make the first example work.

This commit is contained in:
Mathias Vorreiter Pedersen
2024-08-28 15:01:49 +01:00
parent 626328c014
commit f21cde2365
3 changed files with 155 additions and 4 deletions

View File

@@ -75,7 +75,95 @@ predicate succExit(CfgScope scope, Ast last, Completion c) { scope.exit(last, c)
/** Defines the CFG by dispatch on the various AST types. */
module Trees {
// TODO
class ScriptBlockTree extends PreOrderTree instanceof ScriptBlock {
final override predicate last(AstNode last, Completion c) {
last(super.getEndBlock(), last, c)
or
not exists(super.getEndBlock()) and
last(super.getProcessBlock(), last, c)
or
not exists(super.getEndBlock()) and
not exists(super.getProcessBlock()) and
last(super.getBeginBlock(), last, c)
or
not exists(super.getEndBlock()) and
not exists(super.getProcessBlock()) and
not exists(super.getBeginBlock()) and
last = this and
completionIsSimple(c)
}
final override predicate propagatesAbnormal(AstNode child) {
child = [super.getBeginBlock(), super.getProcessBlock(), super.getEndBlock()]
}
final override predicate succ(AstNode pred, AstNode succ, Completion c) {
pred = this and
(
first(super.getBeginBlock(), succ)
or
not exists(super.getBeginBlock()) and
first(super.getProcessBlock(), succ)
or
not exists(super.getBeginBlock()) and
not exists(super.getProcessBlock()) and
first(super.getEndBlock(), succ)
) and
completionIsSimple(c)
or
last(super.getBeginBlock(), pred, c) and
c instanceof NormalCompletion and
(
first(super.getProcessBlock(), succ)
or
not exists(super.getProcessBlock()) and
first(super.getEndBlock(), succ)
or
not exists(super.getProcessBlock()) and
not exists(super.getEndBlock()) and
succ = this
)
or
last(super.getProcessBlock(), pred, c) and
c instanceof NormalCompletion and
(
// If we process multiple items we will loop back to the process block
first(super.getProcessBlock(), succ)
or
// Once we're done process all items we will go to the end block
first(super.getEndBlock(), succ)
)
}
}
class NamedBlockTree extends StandardPostOrderTree instanceof NamedBlock {
// TODO: Handle trap
override AstNode getChildNode(int i) { result = super.getStatement(i) }
}
class AssignStmtTree extends StandardPostOrderTree instanceof AssignStmt {
override AstNode getChildNode(int i) {
i = 0 and result = super.getLeftHandSide()
or
i = 1 and result = super.getRightHandSide()
}
}
class VarAccessTree extends LeafTree instanceof VarAccess { }
class BinaryExprTree extends StandardPostOrderTree instanceof BinaryExpr {
override AstNode getChildNode(int i) {
i = 0 and result = super.getLeft()
or
i = 1 and result = super.getRight()
}
}
class ConstExprTree extends LeafTree instanceof ConstExpr { }
class CmdExprTree extends StandardPreOrderTree instanceof CmdExpr {
override AstNode getChildNode(int i) { i = 0 and result = super.getExpr() }
}
}
private import Scope

View File

@@ -0,0 +1,59 @@
global.ps1:
# 1| {...}
#-----| -> c
# 1| enter global.ps1
#-----| -> global.ps1
# 1| exit global.ps1
# 1| exit global.ps1 (normal)
#-----| -> exit global.ps1
# 1| global.ps1
#-----| -> a
# 2| a
#-----| -> 1
# 2| ...=...
#-----| -> b
# 2| 1
#-----| -> ...=...
# 2| 1
#-----| -> 1
# 3| b
#-----| -> 2
# 3| ...=...
#-----| -> {...}
# 3| 2
#-----| -> ...=...
# 3| 2
#-----| -> 2
# 5| {...}
#-----| -> exit global.ps1 (normal)
# 6| c
#-----| -> ...+...
# 6| ...=...
#-----| -> {...}
# 6| a
#-----| -> b
# 6| ...+...
#-----| -> ...=...
# 6| ...+...
#-----| -> a
# 6| b
#-----| -> ...+...

View File

@@ -1,3 +1,7 @@
$a = 1
$b = 2
$c = $a + $b
Begin {
$a = 1
$b = 2
}
End {
$c = $a + $b
}