Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 11 additions & 6 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
plugins {
id 'org.jetbrains.kotlin.jvm' version '1.6.21'
id 'org.jetbrains.kotlin.jvm' version '1.8.22'
id 'com.github.johnrengelman.shadow' version '5.2.0'
id 'antlr'
id "kr.motd.sphinx" version "2.10.0"
Expand All @@ -17,7 +17,7 @@ java {

repositories {
mavenCentral()
maven { url "https://overture.au.dk/artifactory/libs-release/" }
maven { url "https://jitpack.io" }
}

test {
Expand All @@ -35,20 +35,25 @@ dependencies {
testImplementation 'io.kotest:kotest-runner-junit5:5.2.3'
testImplementation 'org.jetbrains.kotlin:kotlin-test-junit'
testImplementation 'org.apache.commons:commons-lang3:3.12.0'
testImplementation 'org.apache.jena:jena-fuseki-main:3.16.0'
testImplementation 'org.apache.jena:jena-fuseki-main:4.10.0'
implementation 'com.github.ajalt.clikt:clikt:3.4.2'
implementation 'org.antlr:antlr4:4.8'
antlr 'org.antlr:antlr4:4.8'
implementation 'net.sourceforge.owlapi:org.semanticweb.hermit:1.4.5.519'
implementation 'org.slf4j:slf4j-simple:1.7.25'
implementation 'org.apache.jena:apache-jena-libs:3.16.0'
implementation 'org.apache.jena:jena-core:3.16.0'
implementation 'org.apache.jena:apache-jena-libs:4.10.0'
implementation 'org.apache.jena:jena-core:4.10.0'
implementation 'org.siani.javafmi:fmu-wrapper:2.26.3'
implementation "com.influxdb:influxdb-client-kotlin:2.3.0"
implementation 'com.sksamuel.hoplite:hoplite-core:1.4.1'
implementation 'com.sksamuel.hoplite:hoplite-yaml:1.4.1'
implementation 'com.github.owlcs:ontapi:2.1.0'
implementation 'com.github.owlcs:ontapi:3.0.5'
implementation 'org.jline:jline:3.21.0'
implementation 'com.github.streamreasoning.rsp4j:api:1.1.8'
implementation 'com.github.streamreasoning.rsp4j:yasper:1.1.8'
implementation 'com.github.streamreasoning.rsp4j:io:1.1.8'
implementation 'com.github.streamreasoning.rsp4j:dsms:1.1.8'
implementation 'com.github.streamreasoning.rsp4j:csparql2:1.1.8'
}


Expand Down
20 changes: 17 additions & 3 deletions src/main/antlr/While.g4
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,10 @@ SIMULATE : 'simulate';
VALIDATE : 'validate';
CLASSIFY : 'classify';
ADAPT : 'adapt';
MONITOR : 'monitor';
TICK : 'tick';
WINDOW : 'window';
PUSH_STATIC: 'pushStatic';
BREAKPOINT : 'breakpoint';
SUPER : 'super';
DESTROY : 'destroy';
Expand All @@ -49,6 +52,8 @@ CLASSIFIES: 'classifies';
RETRIEVES: 'retrieves';
DOMAIN : 'domain';
CONTEXT : 'context';
STREAMER : 'streamer';
EMITS : 'emits';

//Keywords: constants
TRUE : 'True';
Expand Down Expand Up @@ -94,6 +99,9 @@ FMU : 'FMO';
PORT : 'port';
SPARQLMODE : 'SPARQL';
INFLUXMODE : 'INFLUXDB';
// MONITORTYPE : 'Monitor';
// QUERYRESULTTYPE : 'QueryResult';
CLOCK : 'clock';
// Note that the IN, OUT constants are also used in
// TypeChecker.kt:translateType in the FMU branch; adapt strings there if
// changing the syntax here
Expand All @@ -117,13 +125,13 @@ namelist : NAME (COMMA NAME)*;
program : (class_def)* MAIN statement END (class_def)*;

//classes
class_def : (abs=ABSTRACT)? (hidden=HIDE)? CLASS className = NAME (LT namelist GT)? (EXTENDS superType = type)? OPARAN (external=fieldDeclList)? CPARAN
class_def : (abs=ABSTRACT)? (hidden=HIDE)? (streamer=STREAMER)? CLASS className = NAME (LT namelist GT)? (EXTENDS superType = type)? OPARAN (external=fieldDeclList)? CPARAN
(internal = fieldDeclInitList)?
(models_block)?
(classifies_block (retrieves_block)?)?
method_def*
END;
method_def : (abs=ABSTRACT)? (builtinrule=RULE)? (domainrule=DOMAIN)? (overriding=OVERRIDE)? type NAME OPARAN paramList? CPARAN (statement END)?;
method_def : (abs=ABSTRACT)? (builtinrule=RULE)? (domainrule=DOMAIN)? (overriding=OVERRIDE)? type NAME OPARAN paramList? CPARAN emits_block? (statement END)?;

models_block : MODELS owldescription=STRING SEMI #simple_models_block
| MODELS OPARAN guard=expression CPARAN owldescription=STRING SEMI models_block #complex_models_block
Expand All @@ -132,14 +140,19 @@ classifies_block : CLASSIFIES owldescription=STRING SEMI # adapt
;
retrieves_block : RETRIEVES selectquery=STRING SEMI # adaptation_retrieves_block
;
emits_block : EMITS OPARAN expression (COMMA expression)* CPARAN;

//Statements
statement : SKIP_S SEMI # skip_statment
| ((declType = type)? target=expression ASS)? CLASSIFY OPARAN context=expression CPARAN SEMI # classify_statement
| ADAPT OPARAN adapter=expression CPARAN SEMI # adapt_statement
| (declType = type)? expression ASS expression SEMI # assign_statement
| (declType = type)? target=expression ASS MONITOR OPARAN registeredQuery=expression (COMMA expression)* CPARAN SEMI # monitor_statement
| (clock = CLOCK)? (declType = type)? expression ASS expression SEMI # assign_statement
| ((declType = type)? target=expression ASS)? SUPER OPARAN (expression (COMMA expression)*)? CPARAN SEMI # super_statement
| RETURN expression SEMI # return_statement
| fmu=expression DOT TICK OPARAN time=expression CPARAN SEMI # tick_statement
| (declType = type)? target=expression ASS WINDOW OPARAN monitor=expression CPARAN SEMI # window_statement
| (declType = type)? target=expression ASS PUSH_STATIC OPARAN sources=expression CPARAN SEMI # pushStatic_statement
| ((declType = type)? target=expression ASS)? expression DOT NAME OPARAN (expression (COMMA expression)*)? CPARAN SEMI # call_statement
// TODO: allow new statements without assignment
| (declType = type)? target=expression ASS NEW newType = type OPARAN (expression (COMMA expression)*)? CPARAN (MODELS owldescription = expression)? SEMI # create_statement
Expand Down Expand Up @@ -194,6 +207,7 @@ expression : THIS # this_expression
type : NAME #simple_type
| NAME LT typelist GT #nested_type
| FMU OBRACK fmuParamList? CBRACK #fmu_type
// | MONITORTYPE LT typelist GT #monitor_type
;
typelist : type (COMMA type)*;
param : type NAME;
Expand Down
63 changes: 61 additions & 2 deletions src/main/kotlin/no/uio/microobject/ast/Translate.kt
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class Translate : WhileBaseVisitor<ProgramElement>() {
private val classifiesTable: MutableMap<String, Pair<String, String>> = mutableMapOf()
private val checkClassifiesTable: MutableMap<String, MutableMap<String, Pair<String, String>>> = mutableMapOf()
private val contextTable : MutableMap<String, String> = mutableMapOf()
private val streamersTable : MutableMap<String, MutableMap<String, MutableSet<Expression>>> = mutableMapOf()

private fun translateModels(ctx : Models_blockContext) : Pair<List<Pair<Expression, String>>, String>{
if(ctx is Simple_models_blockContext)
Expand Down Expand Up @@ -75,6 +76,11 @@ class Translate : WhileBaseVisitor<ProgramElement>() {
addClassifyQuery(cl.className.text, cl.classifies_block(), null)
}
}

// create streamer configuration
if (cl.streamer != null) {
streamersTable[cl.className.text] = mutableMapOf()
}
val inFields = if(cl.external != null) {
var res = listOf<FieldInfo>()
if(cl.external.fieldDecl() != null) {
Expand Down Expand Up @@ -141,6 +147,14 @@ class Translate : WhileBaseVisitor<ProgramElement>() {
val params = if (nm.paramList() != null) paramListTranslate(nm.paramList()) else listOf()
res[nm.NAME().text] = MethodInfo(SkipStmt(ctx!!.start.line), params, nm.builtinrule != null, nm.domainrule != null, cl.className.text, metType)
}
if (nm.emits_block() != null) {
if (!streamersTable.containsKey(cl.className.text))
throw Exception("Class with methods containing emits clause must be a streamer: ${nm.NAME().text}")

streamersTable[cl.className.text]!![nm.NAME().text] = mutableSetOf()
for(i in 0 until nm.emits_block().expression().size)
streamersTable[cl.className.text]!![nm.NAME().text]!! += visit(nm.emits_block().expression(i)) as Expression
}
}
table[cl.className.text] = Pair(fields, res)
}
Expand Down Expand Up @@ -179,7 +193,7 @@ class Translate : WhileBaseVisitor<ProgramElement>() {

return Pair(
StackEntry(visit(ctx.statement()) as Statement, mutableMapOf(), Names.getObjName("_Entry_"), Names.getStackId()),
StaticTable(fieldTable, methodTable, hierarchy, modelsTable, hidden, owldescr, checkClassifiesTable, contextTable)
StaticTable(fieldTable, methodTable, hierarchy, modelsTable, hidden, owldescr, checkClassifiesTable, contextTable, streamersTable)
)
}

Expand Down Expand Up @@ -402,6 +416,50 @@ class Translate : WhileBaseVisitor<ProgramElement>() {
return SimulationStmt(target, path, res, ctx!!.start.line, declares)
}

override fun visitMonitor_statement(ctx: Monitor_statementContext?): ProgramElement {
val target = visit(ctx!!.target) as Location
if(ctx.declType != null) {
val decl = getClassDecl(ctx)
val className = if(decl == null) ERRORTYPE.name else decl!!.className.text
val targetType = TypeChecker.translateType(ctx.declType, className, mutableMapOf())
target.setType(targetType)
}

val query = visit(ctx!!.registeredQuery) as Expression
val ll = emptyList<Expression>().toMutableList()
for(i in 2 until ctx!!.expression().size)
ll += visit(ctx.expression(i)) as Expression

return MonitorStmt(target, query, ll, ctx!!.start.line, target.getType())
}

override fun visitPushStatic_statement(ctx: PushStatic_statementContext?): ProgramElement {
val target = visit(ctx!!.target) as Location
if(ctx.declType != null) {
val decl = getClassDecl(ctx)
val className = if(decl == null) ERRORTYPE.name else decl!!.className.text
val targetType = TypeChecker.translateType(ctx.declType, className, mutableMapOf())
target.setType(targetType)
}

val sources = visit(ctx!!.sources) as Expression

return PushStaticStmt(target, sources, ctx!!.start.line, target.getType())
}


override fun visitWindow_statement(ctx: Window_statementContext?): ProgramElement {
val target = visit(ctx!!.target) as Location
if(ctx.declType != null) {
val decl = getClassDecl(ctx)
val className = if(decl == null) ERRORTYPE.name else decl!!.className.text
val targetType = TypeChecker.translateType(ctx.declType, className, mutableMapOf())
target.setType(targetType)
}
val monitor = visit(ctx!!.monitor) as Expression
return WindowStmt(target, monitor, ctx!!.start.line, declares=target.getType())
}

override fun visitTick_statement(ctx: Tick_statementContext?): ProgramElement {
return TickStmt(visit(ctx!!.fmu) as Expression, visit(ctx!!.time) as Expression )
}
Expand All @@ -418,7 +476,8 @@ class Translate : WhileBaseVisitor<ProgramElement>() {
val def = getClassDecl(ctx as RuleContext)
val declares = if(ctx!!.declType == null) null else
TypeChecker.translateType(ctx.declType, if(def != null) def!!.className.text else ERRORTYPE.name, mutableMapOf())
return AssignStmt(visit(ctx!!.expression(0)) as Location, visit(ctx.expression(1)) as Expression, ctx!!.start.line, declares)
val isClock = if(ctx.clock == null) false else true
return AssignStmt(visit(ctx!!.expression(0)) as Location, visit(ctx.expression(1)) as Expression, isClock, ctx!!.start.line, declares)
}

override fun visitSkip_statment(ctx: Skip_statmentContext?): ProgramElement {
Expand Down
12 changes: 10 additions & 2 deletions src/main/kotlin/no/uio/microobject/ast/stmt/AssignStmt.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@ import no.uio.microobject.runtime.Memory
import no.uio.microobject.runtime.StackEntry
import no.uio.microobject.type.BaseType
import no.uio.microobject.type.Type
import no.uio.microobject.type.INTTYPE

// Assignment, where value cannot refer to calls or object creations.
data class AssignStmt(val target : Location, val value : Expression, val pos : Int = -1, val declares: Type?) :
data class AssignStmt(val target : Location, val value : Expression, val isClock: Boolean = false, val pos : Int = -1, val declares: Type?) :
Statement {
override fun toString(): String = "$target := $value"
override fun getRDF(): String {
Expand All @@ -28,7 +29,14 @@ data class AssignStmt(val target : Location, val value : Expression, val pos : I
override fun eval(heapObj: Memory, stackFrame : StackEntry, interpreter: Interpreter) : EvalResult {
val res = interpreter.eval(value, stackFrame)
when (target) {
is LocalVar -> stackFrame.store[target.name] = res
is LocalVar -> {
if (isClock && interpreter.streamManager.clockVar == null) {
interpreter.streamManager.clockVar = target.name
}
if (interpreter.streamManager.clockVar != null && target.name.equals(interpreter.streamManager.clockVar)
&& res.tag == INTTYPE) interpreter.streamManager.updateClock(res.literal.toLong())
stackFrame.store[target.name] = res
}
is OwnVar -> {
val got = interpreter.staticInfo.fieldTable[(stackFrame.obj.tag as BaseType).name] ?: throw Exception("Cannot find class ${stackFrame.obj.tag.name}")
if (!got.map {it.name} .contains(target.name))
Expand Down
8 changes: 7 additions & 1 deletion src/main/kotlin/no/uio/microobject/ast/stmt/CallStmt.kt
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,14 @@ data class CallStmt(val target : Location, val callee : Location, val method : S
for (i in m.params.indices) {
newMemory[m.params[i]] = interpreter.eval(params[i], stackFrame)
}

var emitFromMethod: String? = null
if (interpreter.staticInfo.streamersTable.containsKey(newObj.tag.name) &&
interpreter.staticInfo.streamersTable[newObj.tag.name]!!.containsKey(method))
emitFromMethod = method

return EvalResult(
StackEntry(StoreReturnStmt(target), stackFrame.store, stackFrame.obj, stackFrame.id),
StackEntry(StoreReturnStmt(target, emitFromMethod=emitFromMethod), stackFrame.store, stackFrame.obj, stackFrame.id),
listOf(StackEntry(m.stmt, newMemory, newObj, Names.getStackId()))
)
}
Expand Down
3 changes: 3 additions & 0 deletions src/main/kotlin/no/uio/microobject/ast/stmt/ConstructStmt.kt
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,9 @@ data class ConstructStmt(val target : Location, val query: Expression, val param
newListMemory["next"] = list
interpreter.heap[newListName] = newListMemory
list = newListName
if (interpreter.staticInfo.streamersTable.containsKey(className)) {
interpreter.streamManager.registerStream(className, newObjName)
}
}
}
return replaceStmt(AssignStmt(target, list, declares = declares), stackFrame)
Expand Down
3 changes: 3 additions & 0 deletions src/main/kotlin/no/uio/microobject/ast/stmt/CreateStmt.kt
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ data class CreateStmt(val target : Location, val className: String, val params :
interpreter.heap[name] = newMemory
val localFrame = StackEntry(SkipStmt(), mutableMapOf(Pair("this", name)),name,0)
n.filter { it.internalInit != null }.forEach { newMemory[it.name] = interpreter.eval(it.internalInit!!, localFrame) }
if (interpreter.staticInfo.streamersTable.containsKey(className)) {
interpreter.streamManager.registerStream(className, name)
}
return replaceStmt(AssignStmt(target, name, declares = declares), stackFrame)
}
}
Loading