Skip to content

Commit 5267b9f

Browse files
committed
lfc: introducing LF-IR
1 parent 553126f commit 5267b9f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+783
-648
lines changed

lfc/bin/lfc-dev

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/bin/bash
1+
#!/nix/store/5mh7kaj2fyv8mk4sfq1brwxgc02884wi-bash-5.2p37/bin/bash
22

33
#============================================================================
44
# Description: Build and run the Lingua Franca compiler (lfc).

lfc/cli/base/src/main/java/org/lflang/cli/CliBase.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ public List<LfIssue> printErrorsIfAny() {
298298
*/
299299
public void validateResource(Resource resource) {
300300
assert resource != null;
301-
301+
System.out.println(resource.toString());
302302
List<Issue> issues = this.validator.validate(resource, CheckMode.ALL, CancelIndicator.NullImpl);
303303

304304
for (Issue issue : issues) {

lfc/core/src/main/java/org/lflang/AttributeUtils.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -295,10 +295,10 @@ public static Attribute getJoiningPolicy(Instantiation node) {
295295
return findAttributeByName(node, "joining_policy");
296296
}
297297

298-
public static int getMaxNumberOfPendingEvents(Action node) {
298+
public static int getMaxNumberOfPendingEvents(org.lflang.ir.Action node) {
299299
Attribute attr = findAttributeByName(node, "max_pending_events");
300300
if (attr != null) {
301-
return Integer.valueOf(attr.getAttrParms().get(0).getValue());
301+
return Integer.parseInt(attr.getAttrParms().get(0).getValue());
302302
} else {
303303
return -1;
304304
}

lfc/core/src/main/java/org/lflang/LinguaFranca.xtext

Lines changed: 4 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* The Lingua Franca grammar. */
22

33
/*************
4-
Copyright (c) 2020, The University of California at Berkeley.
4+
Copyright (c) 2025, The University of California at Berkeley.
55

66
Redistribution and use in source and binary forms, with or without modification,
77
are permitted provided that the following conditions are met:
@@ -91,7 +91,6 @@ Reactor:
9191
| (instantiations+=Instantiation)
9292
| (connections+=Connection)
9393
| (reactions+=Reaction)
94-
| (modes+=Mode)
9594
)* '}';
9695

9796

@@ -170,17 +169,6 @@ Output:
170169
Timer:
171170
(attributes+=Attribute)* 'timer' name=ID ('(' offset=Expression (',' period=Expression)? ')')? ';'?;
172171

173-
Mode:
174-
{Mode} (initial?='initial')? 'mode' (name=ID)?
175-
'{' (
176-
(stateVars+=StateVar) |
177-
(timers+=Timer) |
178-
(actions+=Action) |
179-
(watchdogs+=Watchdog) |
180-
(instantiations+=Instantiation) |
181-
(connections+=Connection) |
182-
(reactions+=Reaction)
183-
)* '}';
184172

185173
// Action that has either a physical or logical origin.
186174
//
@@ -204,7 +192,7 @@ Reaction:
204192
(name=ID)?
205193
('(' (triggers+=TriggerRef (',' triggers+=TriggerRef)*)? ')')
206194
( => sources+=VarRef (',' sources+=VarRef)*)?
207-
('->' effects+=VarRefOrModeTransition (',' effects+=VarRefOrModeTransition)*)?
195+
('->' effects+=VarRef (',' effects+=VarRef)*)?
208196
(code=Code)? (stp=STP)? (deadline=Deadline)? (maxWait=MaxWait)? (delimited?=';')?
209197
;
210198

@@ -220,7 +208,7 @@ Deadline:
220208
Watchdog:
221209
(attributes+=Attribute)*
222210
'watchdog' name=ID '(' timeout=Expression ')'
223-
('->' effects+=VarRefOrModeTransition (',' effects+=VarRefOrModeTransition)*)?
211+
('->' effects+=VarRef (',' effects+=VarRef)*)?
224212
code=Code;
225213

226214
STP:
@@ -287,15 +275,12 @@ TypedVariable:
287275
;
288276

289277
Variable:
290-
TypedVariable | Timer | Mode | Watchdog;
278+
TypedVariable | Timer | Watchdog;
291279

292280
VarRef:
293281
(variable=[Variable] | container=[Instantiation] '.' variable=[Variable]
294282
| interleaved?='interleaved' '(' (variable=[Variable] | container=[Instantiation] '.' variable=[Variable]) ')') ('as' (alias=ID))?
295283
;
296-
VarRefOrModeTransition returns VarRef:
297-
VarRef | transition=ModeTransition '(' variable=[Mode] ')';
298-
299284
Assignment:
300285
lhs=[Parameter]
301286
rhs=Initializer
@@ -507,9 +492,6 @@ enum Visibility:
507492
enum BuiltinTrigger:
508493
STARTUP='startup' | SHUTDOWN='shutdown' | RESET='reset';
509494

510-
enum ModeTransition:
511-
RESET='reset' | HISTORY='history';
512-
513495
// Note: time units are not keywords, otherwise it would reserve
514496
// a lot of useful identifiers (like 's' or 'd').
515497
// The validator ensures the unit is valid.
Lines changed: 61 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -1,107 +1,93 @@
11
package org.lflang.generator.uc
22

3-
import org.lflang.*
4-
import org.lflang.AttributeUtils.getMaxNumberOfPendingEvents
53
import org.lflang.generator.PrependOperator
6-
import org.lflang.generator.orZero
7-
import org.lflang.generator.uc.UcPortGenerator.Companion.arrayLength
8-
import org.lflang.generator.uc.UcPortGenerator.Companion.isArray
9-
import org.lflang.generator.uc.UcReactorGenerator.Companion.codeType
10-
import org.lflang.generator.uc.UcReactorGenerator.Companion.getEffects
11-
import org.lflang.generator.uc.UcReactorGenerator.Companion.getObservers
12-
import org.lflang.generator.uc.UcReactorGenerator.Companion.getSources
13-
import org.lflang.generator.uc.UcReactorGenerator.Companion.hasShutdown
14-
import org.lflang.generator.uc.UcReactorGenerator.Companion.hasStartup
15-
import org.lflang.lf.*
4+
import org.lflang.ir.Reactor
5+
import org.lflang.ir.Action
6+
import org.lflang.ir.Shutdown
7+
import org.lflang.ir.Startup
168

179
class UcActionGenerator(private val reactor: Reactor) {
18-
19-
companion object {
20-
public val Action.maxNumPendingEvents
21-
get(): Int {
22-
val num = getMaxNumberOfPendingEvents(this)
23-
return if (num > 0) num else 1
24-
}
25-
}
26-
27-
/** Returns the C Enum representing the type of action. */
28-
private val Action.actionType
29-
get(): String = if (isPhysical) "PhysicalAction" else "LogicalAction"
30-
3110
private fun generateSelfStruct(action: Action): String {
32-
if (action.type == null) {
33-
return "LF_DEFINE_ACTION_STRUCT_VOID(${reactor.codeType}, ${action.name}, ${action.actionType}, ${reactor.getEffects(action).size}, ${reactor.getSources(action).size}, ${reactor.getObservers(action).size}, ${action.maxNumPendingEvents});"
34-
} else if (action.type.isArray) {
35-
return "LF_DEFINE_ACTION_STRUCT_ARRAY(${reactor.codeType}, ${action.name}, ${action.actionType}, ${reactor.getEffects(action).size}, ${reactor.getSources(action).size}, ${reactor.getObservers(action).size}, ${action.maxNumPendingEvents}, ${action.type.id}, ${action.type.arrayLength});"
36-
} else {
37-
return "LF_DEFINE_ACTION_STRUCT(${reactor.codeType}, ${action.name}, ${action.actionType}, ${reactor.getEffects(action).size}, ${reactor.getSources(action).size}, ${reactor.getObservers(action).size}, ${action.maxNumPendingEvents}, ${action.type.toText()});"
38-
}
11+
return if (action.type.isVoid) {
12+
"LF_DEFINE_ACTION_STRUCT_VOID(${reactor.codeType}, ${action.lfName}, ${action.actionType}, ${action.getEffects().size}, ${action.getSources().size}, ${action.getObservers().size}, ${action.maxNumPendingEvents});"
13+
} else if (action.type.isArray) {
14+
"LF_DEFINE_ACTION_STRUCT_ARRAY(${reactor.codeType}, ${action.lfName}, ${action.actionType}, ${action.getEffects().size}, ${action.getSources().size}, ${action.getObservers().size}, ${action.maxNumPendingEvents}, ${action.type.targetCode}, ${action.type.arrayLength});"
15+
} else {
16+
"LF_DEFINE_ACTION_STRUCT(${reactor.codeType}, ${action.lfName}, ${action.actionType}, ${action.getEffects().size}, ${action.getSources().size}, ${action.getObservers().size}, ${action.maxNumPendingEvents}, ${action.type.targetCode});"
17+
}
3918
}
4019

4120
private fun generateCtor(action: Action) =
4221
with(PrependOperator) {
4322
"""
44-
|LF_DEFINE_ACTION_CTOR${if (action.type == null) "_VOID" else ""}(${reactor.codeType}, ${action.name}, ${action.actionType}, ${reactor.getEffects(action).size}, ${reactor.getSources(action).size}, ${reactor.getObservers(action).size}, ${action.maxNumPendingEvents} ${if (action.type != null) ", ${action.type.toText()}" else ""});
23+
|LF_DEFINE_ACTION_CTOR${if (action.type.isVoid) "_VOID" else ""}(${reactor.codeType}, ${action.lfName}, ${action.actionType}, ${action.getEffects().size}, ${action.getSources().size}, ${action.getObservers().size}, ${action.maxNumPendingEvents} ${if (action.type.isVoid) ", ${action.type.targetCode}" else ""});
4524
|
4625
"""
4726
.trimMargin()
4827
}
4928

50-
private fun generateCtor(builtin: BuiltinTrigger) =
51-
(if (builtin == BuiltinTrigger.STARTUP) "LF_DEFINE_STARTUP_CTOR"
52-
else "LF_DEFINE_SHUTDOWN_CTOR") + "(${reactor.codeType});\n"
5329

54-
fun generateCtors(): String {
55-
var code = reactor.allActions.joinToString(separator = "\n") { generateCtor(it) }
56-
if (reactor.hasStartup) code += generateCtor(BuiltinTrigger.STARTUP)
57-
if (reactor.hasShutdown) code += generateCtor(BuiltinTrigger.SHUTDOWN)
58-
return code
59-
}
30+
fun generateCtors(): String =
31+
reactor.actions.joinToString(separator = "\n") { generateCtor(it) }
6032

61-
private fun generateSelfStruct(builtin: BuiltinTrigger) =
62-
(if (builtin == BuiltinTrigger.STARTUP) "LF_DEFINE_STARTUP_STRUCT"
63-
else "LF_DEFINE_SHUTDOWN_STRUCT") +
64-
"(${reactor.codeType}, ${reactor.getEffects(builtin).size}, ${reactor.getObservers(builtin).size});\n"
33+
fun generateSelfStructs(): String =
34+
reactor.actions.joinToString(separator = "\n") { generateSelfStruct(it) }
6535

66-
fun generateSelfStructs(): String {
67-
var code = reactor.allActions.joinToString(separator = "\n") { generateSelfStruct(it) }
68-
if (reactor.hasStartup) {
69-
code += generateSelfStruct(BuiltinTrigger.STARTUP)
70-
}
71-
if (reactor.hasShutdown) {
72-
code += generateSelfStruct(BuiltinTrigger.SHUTDOWN)
73-
}
74-
return code
75-
}
7636

77-
fun generateReactorStructFields(): String {
78-
var code =
79-
reactor.allActions.joinToString(
37+
fun generateReactorStructFields(): String =
38+
reactor.actions.joinToString(
8039
prefix = "// Actions and builtin triggers\n", separator = "\n", postfix = "\n") {
81-
"LF_ACTION_INSTANCE(${reactor.codeType}, ${it.name});"
40+
"LF_ACTION_INSTANCE(${reactor.codeType}, ${it.lfName});"
8241
}
83-
if (reactor.hasStartup) code += "LF_STARTUP_INSTANCE(${reactor.codeType});"
84-
if (reactor.hasShutdown) code += "LF_SHUTDOWN_INSTANCE(${reactor.codeType});"
85-
return code
86-
}
8742

8843
private fun generateReactorCtorCode(action: Action) =
89-
"LF_INITIALIZE_ACTION(${reactor.codeType}, ${action.name}, ${action.minDelay.orZero().toCCode()}, ${action.minSpacing.orZero().toCCode()});"
90-
91-
private fun generateReactorCtorCodeStartup() = "LF_INITIALIZE_STARTUP(${reactor.codeType});"
44+
"LF_INITIALIZE_ACTION(${reactor.codeType}, ${action.lfName}, ${action.minDelay.toCCode()}, ${action.minSpacing.toCCode()});"
9245

93-
private fun generateReactorCtorCodeShutdown() = "LF_INITIALIZE_SHUTDOWN(${reactor.codeType});"
9446

95-
fun generateReactorCtorCodes(): String {
96-
var code =
97-
reactor.allActions.joinToString(
47+
fun generateReactorCtorCodes(): String =
48+
reactor.actions.joinToString(
9849
prefix = "// Initialize actions and builtin triggers\n",
9950
separator = "\n",
10051
postfix = "\n") {
10152
generateReactorCtorCode(it)
10253
}
103-
if (reactor.hasStartup) code += "${generateReactorCtorCodeStartup()}\n"
104-
if (reactor.hasShutdown) code += "${generateReactorCtorCodeShutdown()}\n"
105-
return code
106-
}
54+
}
55+
56+
class BuiltInGenerator(private val reactor: Reactor) {
57+
private fun generateShutdownCtor() =
58+
"LF_DEFINE_SHUTDOWN_CTOR(${reactor.codeType});\n"
59+
60+
private fun generateStartUpCtor() =
61+
"LF_DEFINE_STARTUP_CTOR(${reactor.codeType});\n"
62+
63+
private fun generateShutdownSelfStruct(trigger: Shutdown) =
64+
"LF_DEFINE_SHUTDOWN_STRUCT(${reactor.codeType}, ${trigger.getEffects().size}, ${trigger.getObservers().size});\n"
65+
66+
private fun generateStartupSelfStruct(trigger: Startup) =
67+
"LF_DEFINE_STARTUP_STRUCT(${reactor.codeType}, ${trigger.getEffects().size}, ${trigger.getObservers().size});\n"
68+
69+
70+
private fun generateReactorCtorCodeStartup() = "LF_INITIALIZE_STARTUP(${reactor.codeType});\n"
71+
private fun generateReactorCtorCodeShutdown() = "LF_INITIALIZE_SHUTDOWN(${reactor.codeType});\n"
72+
73+
fun generateCtors() : String {
74+
var code = String()
75+
if (reactor.hasStartup) code += generateStartUpCtor()
76+
if (reactor.hasShutdown) code += generateShutdownCtor()
77+
return code
78+
}
79+
80+
fun generateSelfStructs(): String {
81+
var code = String()
82+
if (reactor.hasStartup) code += generateStartupSelfStruct(reactor.startup!!)
83+
if (reactor.hasShutdown) code += generateShutdownSelfStruct(reactor.shutdown!!)
84+
return code
85+
}
86+
87+
fun generateReactorCtorCodes(): String {
88+
var code = String()
89+
if (reactor.hasStartup) code += generateReactorCtorCodeStartup()
90+
if (reactor.hasShutdown) code += generateReactorCtorCodeShutdown()
91+
return code
92+
}
10793
}

lfc/core/src/main/kotlin/org/lflang/generator/uc/UcCmakeGenerator.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import java.nio.file.Path
44
import kotlin.io.path.name
55
import org.lflang.*
66
import org.lflang.generator.PrependOperator
7+
import org.lflang.generator.uc.federated.UcFederate
78
import org.lflang.lf.Instantiation
89
import org.lflang.target.TargetConfig
910
import org.lflang.target.property.*

0 commit comments

Comments
 (0)