(WIP) implementing CBD language... Meta-meta-model: Association inherits from Class. Matcher accepts pivot. Add generic graphviz renderer.

This commit is contained in:
Joeri Exelmans 2024-11-07 09:46:29 +01:00
parent a26ceef10f
commit 1eb8a84553
25 changed files with 542 additions and 170 deletions

View file

@ -1,34 +1,34 @@
# Adder, two inputs, one output
adder:Function {
func = ```
n2_out = in0 + in1
n2_out = n0_in + n1_in
```;
}
n0_in:IntInPort
n1_in:IntInPort
n2_out:IntOutPort
n0_in:InPort
n1_in:InPort
n2_out:OutPort
:hasInPort (adder -> n0_in)
:hasInPort (adder -> n1_in)
:hasOutPort (adder -> n2_out)
# Delay block 0
d0:Delay
d0_in:IntInPort
d0_out:IntOutPort
d0_in:InPort
d0_out:OutPort
:hasInPort (d0 -> d0_in)
:hasOutPort (d0 -> d0_out)
# Delay block 1
d1:Delay
d1_in:IntInPort
d1_out:IntOutPort
d1_in:InPort
d1_out:OutPort
:hasInPort (d1 -> d1_in)
:hasOutPort (d1 -> d1_out)
:intLink (n2_out -> d1_in)
:intLink (d1_out -> n1_in)
:intLink (d1_out -> d0_in)
:intLink (d1_out -> n0_in)
# Connections
conn0:link (n2_out -> d1_in) # n2 becomes n1 in next step
conn1:link (d1_out -> d0_in) # n1 becomes n0 in next step
conn2:link (d1_out -> n1_in) # n1 input to adder
conn3:link (d0_out -> n0_in) # n0 input to adder

View file

@ -1,7 +1,8 @@
d0s:IntState {
# Initial state for both delay blocks:
d0s:State {
state = 0;
}
d1s:IntState {
d1s:State {
state = 1;
}
:delay2State (d0 -> d0s)

View file

@ -3,10 +3,10 @@ Block:Class {
}
InPort:Class {
abstract = True;
# abstract = True;
}
OutPort:Class {
abstract = True;
# abstract = True;
}
hasInPort:Association (Block -> InPort) {
@ -77,8 +77,8 @@ Delay:Class {
out_type = None
else:
out_type = get_type_name(get_target(get_outgoing(this, "hasOutPort")[0]))
if in_type != None and out_type != None and in_type[0:3] != out_type[0:3]:
errors.append(f"Inport type ({in_type}) differs from outport type ({out_type})")
# if in_type != None and out_type != None and in_type[0:3] != out_type[0:3]:
# errors.append(f"Inport type ({in_type}) differs from outport type ({out_type})")
errors
```;
}
@ -90,40 +90,40 @@ Delay:Class {
# Object Diagrams are statically typed, so we must create in/out-ports, and MemorySlots for all primitive types:
# Port types
# # Port types
BoolInPort:Class
IntInPort:Class
StrInPort:Class
# BoolInPort:Class
# IntInPort:Class
# StrInPort:Class
BoolOutPort:Class
IntOutPort:Class
StrOutPort:Class
# BoolOutPort:Class
# IntOutPort:Class
# StrOutPort:Class
:Inheritance (BoolInPort -> InPort)
:Inheritance (IntInPort -> InPort)
:Inheritance (StrInPort -> InPort)
# :Inheritance (BoolInPort -> InPort)
# :Inheritance (IntInPort -> InPort)
# :Inheritance (StrInPort -> InPort)
:Inheritance (BoolOutPort -> OutPort)
:Inheritance (IntOutPort -> OutPort)
:Inheritance (StrOutPort -> OutPort)
# :Inheritance (BoolOutPort -> OutPort)
# :Inheritance (IntOutPort -> OutPort)
# :Inheritance (StrOutPort -> OutPort)
# Link types
# # Link types
boolLink:Association (BoolOutPort -> BoolInPort)
intLink:Association (IntOutPort -> IntInPort)
strLink:Association (StrOutPort -> StrInPort)
# boolLink:Association (BoolOutPort -> BoolInPort)
# intLink:Association (IntOutPort -> IntInPort)
# strLink:Association (StrOutPort -> StrInPort)
:Inheritance (boolLink -> link)
:Inheritance (intLink -> link)
:Inheritance (strLink -> link)
# :Inheritance (boolLink -> link)
# :Inheritance (intLink -> link)
# :Inheritance (strLink -> link)
# Delay block types
# # Delay block types
BoolDelay:Class
IntDelay:Class
StrDelay:Class
# BoolDelay:Class
# IntDelay:Class
# StrDelay:Class
:Inheritance (BoolDelay -> Delay)
:Inheritance (IntDelay -> Delay)
:Inheritance (StrDelay -> Delay)
# :Inheritance (BoolDelay -> Delay)
# :Inheritance (IntDelay -> Delay)
# :Inheritance (StrDelay -> Delay)

View file

@ -1,28 +1,58 @@
# Link state ("signal")
# is optional: absent for yet-to-compute signals
intLink_signal:AttributeLink (intLink -> Integer) {
name = "signal";
optional = True;
Signal:Class {
# abstract = True;
}
boolLink_signal:AttributeLink (boolLink -> Boolean) {
Signal_signal:AttributeLink (Signal -> Integer) {
name = "signal";
optional = True;
optional = False;
}
strLink_signal:AttributeLink (strLink -> String) {
name = "signal";
optional = True;
hasSignal:Association (link -> Signal) {
# every Signal has 1 link
source_lower_cardinality = 1;
source_upper_cardinality = 1;
# every link has 0..1 Signals:
target_upper_cardinality = 1;
}
# BoolSignal:Class
# IntSignal:Class
# StrSignal:Class
# :Inheritance (BoolSignal -> Signal)
# :Inheritance (IntSignal -> Signal)
# :Inheritance (StrSignal -> Signal)
# BoolSignal_signal:AttributeLink (BoolSignal -> Boolean) {
# name = "signal";
# optional = False;
# }
# IntSignal_signal:AttributeLink (IntSignal -> Integer) {
# name = "signal";
# optional = False;
# }
# StrSignal_signal:AttributeLink (StrSignal -> String) {
# name = "signal";
# optional = False;
# }
# Delay block state
# mandatory - otherwise we cannot determine the output signal of a delay block
State:Class {
abstract = True;
# abstract = True;
}
State_state:AttributeLink (State -> Integer) {
name = "state";
optional = False;
}
delay2State:Association (Delay -> State) {
source_lower_cardinality = 1;
source_upper_cardinality = 1;
@ -30,26 +60,26 @@ delay2State:Association (Delay -> State) {
target_upper_cardinality = 1;
}
BoolState:Class
IntState:Class
StrState:Class
# BoolState:Class
# IntState:Class
# StrState:Class
:Inheritance (BoolState -> State)
:Inheritance (IntState -> State)
:Inheritance (StrState -> State)
# :Inheritance (BoolState -> State)
# :Inheritance (IntState -> State)
# :Inheritance (StrState -> State)
BoolState_state:AttributeLink (BoolState -> Boolean) {
name = "state";
optional = False;
}
# BoolState_state:AttributeLink (BoolState -> Boolean) {
# name = "state";
# optional = False;
# }
IntState_state:AttributeLink (IntState -> Integer) {
name = "state";
optional = False;
}
# IntState_state:AttributeLink (IntState -> Integer) {
# name = "state";
# optional = False;
# }
StrState_state:AttributeLink (StrState -> String) {
name = "state";
optional = False;
}
# StrState_state:AttributeLink (StrState -> String) {
# name = "state";
# optional = False;
# }

View file

@ -0,0 +1,16 @@
# We look for a Delay-block, its outgoing connection, and its State
delay:RAM_Delay
delay_out:RAM_OutPort # abstract
delay_has_output:RAM_hasOutPort (delay -> delay_out)
some_inport:RAM_InPort # abstract
delay_out_conn:RAM_link (delay_out -> some_inport)
state:RAM_State
delay_to_state:RAM_delay2State (delay -> state)

View file

@ -0,0 +1,14 @@
# From our LHS:
delay_out:RAM_OutPort # abstract
some_inport:RAM_InPort # abstract
delay_out_conn:RAM_link (delay_out -> some_inport) # abstract
# The delay block's outgoing connection already has a signal:
some_signal:RAM_Signal
:RAM_hasSignal (delay_out_conn -> some_signal)

View file

@ -0,0 +1,23 @@
# Our entire LHS (don't delete anything):
delay:RAM_Delay
delay_out:RAM_OutPort # abstract
delay_has_output:RAM_hasOutPort (delay -> delay_out)
some_inport:RAM_InPort # abstract
delay_out_conn:RAM_link (delay_out -> some_inport) # abstract
state:RAM_State
delay_to_state:RAM_delay2State (delay -> state)
# To create:
new_signal:RAM_Signal {
RAM_signal = `get_slot_value(match('state'), 'state')`;
}
:RAM_hasSignal (delay_out_conn -> new_signal)