Wire offline message

This commit is contained in:
Jan-Niclas Loosen
2026-01-17 00:14:44 +01:00
parent 530c597fc1
commit dfd4b4f305
2 changed files with 62 additions and 15 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 82 KiB

View File

@@ -9,6 +9,13 @@ import compiler
import syntax import syntax
# -------------------------------------------------
# Global function environment
# -------------------------------------------------
FUNCTIONS = {} # name -> (func_start, func_end)
# ------------------------------------------------- # -------------------------------------------------
# Expressions — NO CFG NODES # Expressions — NO CFG NODES
# ------------------------------------------------- # -------------------------------------------------
@@ -64,13 +71,21 @@ class SEQ(compiler.SEQ):
class IF(compiler.IF): class IF(compiler.IF):
def cfa(self, pred, end): def cfa(self, pred, end):
cond = CFG_DIAMOND(self) # decision node (condition only)
cond = CFG_DIAMOND(self.cond)
pred.add_child(cond) pred.add_child(cond)
# explicit branch entries
then_entry = CFG_Node()
else_entry = CFG_Node()
cond.add_child(then_entry)
cond.add_child(else_entry)
# join node
join = CFG_Node() join = CFG_Node()
then_end = self.exp1.cfa(cond, end) then_end = self.exp1.cfa(then_entry, end)
else_end = self.exp2.cfa(cond, end) else_end = self.exp2.cfa(else_entry, end)
if then_end is not None: if then_end is not None:
then_end.add_child(join) then_end.add_child(join)
@@ -82,13 +97,19 @@ class IF(compiler.IF):
class WHILE(compiler.WHILE): class WHILE(compiler.WHILE):
def cfa(self, pred, end): def cfa(self, pred, end):
cond = CFG_DIAMOND(self) # loop condition
cond = CFG_DIAMOND(self.cond)
pred.add_child(cond) pred.add_child(cond)
body_end = self.body.cfa(cond, end) # body entry
if body_end is not None: body_entry = CFG_Node()
body_end.add_child(cond) cond.add_child(body_entry)
body_end = self.body.cfa(body_entry, end)
if body_end is not None:
body_end.add_child(cond) # back-edge
# loop exit
after = CFG_Node() after = CFG_Node()
cond.add_child(after) cond.add_child(after)
@@ -96,21 +117,47 @@ class WHILE(compiler.WHILE):
# ------------------------------------------------- # -------------------------------------------------
# Functions / calls # Functions / calls (interprocedural CFG)
# ------------------------------------------------- # -------------------------------------------------
class CALL(compiler.CALL): class CALL(compiler.CALL):
def cfa(self, pred, end): def cfa(self, pred, end):
n = CFG_CALL(self) call = CFG_CALL(self)
pred.add_child(n) pred.add_child(call)
return n
# continuation after return
cont = CFG_Node()
if self.f_name not in FUNCTIONS:
raise RuntimeError(f"Call to undefined function '{self.f_name}'")
f_start, f_end = FUNCTIONS[self.f_name]
# call → function entry
call.add_child(f_start)
# function exit → continuation
f_end.add_child(cont)
return cont
class DECL(compiler.DECL): class DECL(compiler.DECL):
def cfa(self, pred, end): def cfa(self, pred, end):
entry = CFG_Node(self) # function entry / exit
pred.add_child(entry) f_start = CFG_Node(self)
return self.body.cfa(entry, end) f_end = CFG_Node(self)
# register function
FUNCTIONS[self.f_name] = (f_start, f_end)
# build function body
body_end = self.body.cfa(f_start, f_end)
if body_end is not None:
body_end.add_child(f_end)
# function declaration does not alter current control flow
return pred
class LET(compiler.LET): class LET(compiler.LET):
@@ -130,5 +177,5 @@ class RETURN(syntax.EXPRESSION):
def cfa(self, pred, end): def cfa(self, pred, end):
n = CFG_RETURN(self) n = CFG_RETURN(self)
pred.add_child(n) pred.add_child(n)
n.add_child(end) # direct jump to global END n.add_child(end) # return to function exit
return None # no fallthrough return None # no fallthrough