Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
14 changes: 14 additions & 0 deletions compiler/lib/src/main/scala/ast/Ast.scala
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ object Ast {
final case class DefEnum(node: AstNode[Ast.DefEnum]) extends Node
final case class DefStateMachine(node: AstNode[Ast.DefStateMachine]) extends Node
final case class DefStruct(node: AstNode[Ast.DefStruct]) extends Node
final case class DefVector(node: AstNode[Ast.DefVector]) extends Node
final case class SpecCommand(node: AstNode[Ast.SpecCommand]) extends Node
final case class SpecContainer(node: AstNode[Ast.SpecContainer]) extends Node
final case class SpecEvent(node: AstNode[Ast.SpecEvent]) extends Node
Expand Down Expand Up @@ -98,6 +99,17 @@ object Ast {
isDictionaryDef: Boolean
)

/* Vector definition */
final case class DefVector(
name: Ident,
size: AstNode[Expr],
sizePrefixType: Option[AstNode[TypeName]],
eltType: AstNode[TypeName],
default: Option[AstNode[Expr]],
format: Option[AstNode[String]],
isDictionaryDef: Boolean
)

/** Component definition */
final case class DefComponent(
kind: ComponentKind,
Expand Down Expand Up @@ -165,6 +177,7 @@ object Ast {
final case class DefStruct(node: AstNode[Ast.DefStruct]) extends Node
final case class DefSystem(node: AstNode[Ast.DefSystem]) extends Node
final case class DefTopology(node: AstNode[Ast.DefTopology]) extends Node
final case class DefVector(node: AstNode[Ast.DefVector]) extends Node
final case class SpecInclude(node: AstNode[Ast.SpecInclude]) extends Node
final case class SpecLoc(node: AstNode[Ast.SpecLoc]) extends Node
}
Expand Down Expand Up @@ -197,6 +210,7 @@ object Ast {
final case class DefSignal(node: AstNode[Ast.DefSignal]) extends Node
final case class DefState(node: AstNode[Ast.DefState]) extends Node
final case class DefStruct(node: AstNode[Ast.DefStruct]) extends Node
final case class DefVector(node: AstNode[Ast.DefVector]) extends Node
final case class SpecInclude(node: AstNode[Ast.SpecInclude]) extends Node
final case class SpecInitialTransition(node: AstNode[Ast.SpecInitialTransition]) extends Node
}
Expand Down
11 changes: 11 additions & 0 deletions compiler/lib/src/main/scala/ast/AstTransformer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,11 @@ trait AstTransformer {
node: Ast.Annotated[AstNode[Ast.DefTopology]]
): ResultAnnotatedNode[Ast.DefTopology] = Right(default(in), node)

def defVectorAnnotatedNode(
in: In,
node: Ast.Annotated[AstNode[Ast.DefVector]]
): ResultAnnotatedNode[Ast.DefVector] = Right(default(in), node)

def exprArrayNode(in: In, node: AstNode[Ast.Expr], e: Ast.ExprArray): ResultNode[Ast.Expr] =
Right(default(in), node)

Expand Down Expand Up @@ -330,6 +335,8 @@ trait AstTransformer {
transform(defStateMachineAnnotatedNode(in, (pre, node1, post)), Ast.ComponentMember.DefStateMachine(_))
case Ast.ComponentMember.DefStruct(node1) =>
transform(defStructAnnotatedNode(in, (pre, node1, post)), Ast.ComponentMember.DefStruct(_))
case Ast.ComponentMember.DefVector(node1) =>
transform(defVectorAnnotatedNode(in, (pre, node1, post)), Ast.ComponentMember.DefVector(_))
case Ast.ComponentMember.SpecCommand(node1) =>
transform(specCommandAnnotatedNode(in, (pre, node1, post)), Ast.ComponentMember.SpecCommand(_))
case Ast.ComponentMember.SpecContainer(node1) =>
Expand Down Expand Up @@ -456,6 +463,8 @@ trait AstTransformer {
transform(defStateAnnotatedNode(in, (pre, node1, post)), Ast.StateMachineMember.DefState(_))
case Ast.StateMachineMember.DefStruct(node1) =>
transform(defStructAnnotatedNode(in, (pre, node1, post)), Ast.StateMachineMember.DefStruct(_))
case Ast.StateMachineMember.DefVector(node1) =>
transform(defVectorAnnotatedNode(in, (pre, node1, post)), Ast.StateMachineMember.DefVector(_))
case Ast.StateMachineMember.SpecInclude(node1) =>
transform(specIncludeAnnotatedNode(in, (pre, node1, post)), Ast.StateMachineMember.SpecInclude(_))
case Ast.StateMachineMember.SpecInitialTransition(node1) =>
Expand Down Expand Up @@ -503,6 +512,8 @@ trait AstTransformer {
transform(defSystemAnnotatedNode(in, (pre, node1, post)), Ast.ModuleMember.DefSystem(_))
case Ast.ModuleMember.DefTopology(node1) =>
transform(defTopologyAnnotatedNode(in, (pre, node1, post)), Ast.ModuleMember.DefTopology(_))
case Ast.ModuleMember.DefVector(node1) =>
transform(defVectorAnnotatedNode(in, (pre, node1, post)), Ast.ModuleMember.DefVector(_))
case Ast.ModuleMember.SpecInclude(node1) =>
transform(specIncludeAnnotatedNode(in, (pre, node1, post)), Ast.ModuleMember.SpecInclude(_))
case Ast.ModuleMember.SpecLoc(node1) =>
Expand Down
5 changes: 5 additions & 0 deletions compiler/lib/src/main/scala/ast/AstVisitor.scala
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ trait AstVisitor {

def defTopologyAnnotatedNode(in: In, node: Ast.Annotated[AstNode[Ast.DefTopology]]): Out = default(in)

def defVectorAnnotatedNode(in: In, node: Ast.Annotated[AstNode[Ast.DefVector]]): Out = default(in)

def exprArrayNode(in: In, node: AstNode[Ast.Expr], e: Ast.ExprArray): Out = default(in)

def exprArraySubscriptNode(in: In, node: AstNode[Ast.Expr], e: Ast.ExprArraySubscript): Out = default(in)
Expand Down Expand Up @@ -156,6 +158,7 @@ trait AstVisitor {
case Ast.ComponentMember.DefEnum(node1) => defEnumAnnotatedNode(in, (pre, node1, post))
case Ast.ComponentMember.DefStateMachine(node1) => defStateMachineAnnotatedNode(in, (pre, node1, post))
case Ast.ComponentMember.DefStruct(node1) => defStructAnnotatedNode(in, (pre, node1, post))
case Ast.ComponentMember.DefVector(node1) => defVectorAnnotatedNode(in, (pre, node1, post))
case Ast.ComponentMember.SpecCommand(node1) => specCommandAnnotatedNode(in, (pre, node1, post))
case Ast.ComponentMember.SpecContainer(node1) => specContainerAnnotatedNode(in, (pre, node1, post))
case Ast.ComponentMember.SpecEvent(node1) => specEventAnnotatedNode(in, (pre, node1, post))
Expand Down Expand Up @@ -213,6 +216,7 @@ trait AstVisitor {
case Ast.ModuleMember.DefStruct(node1) => defStructAnnotatedNode(in, (pre, node1, post))
case Ast.ModuleMember.DefSystem(node1) => defSystemAnnotatedNode(in, (pre, node1, post))
case Ast.ModuleMember.DefTopology(node1) => defTopologyAnnotatedNode(in, (pre, node1, post))
case Ast.ModuleMember.DefVector(node1) => defVectorAnnotatedNode(in, (pre, node1, post))
case Ast.ModuleMember.SpecInclude(node1) => specIncludeAnnotatedNode(in, (pre, node1, post))
case Ast.ModuleMember.SpecLoc(node1) => specLocAnnotatedNode(in, (pre, node1, post))
}
Expand All @@ -232,6 +236,7 @@ trait AstVisitor {
case Ast.StateMachineMember.DefSignal(node1) => defSignalAnnotatedNode(in, (pre, node1, post))
case Ast.StateMachineMember.DefState(node1) => defStateAnnotatedNode(in, (pre, node1, post))
case Ast.StateMachineMember.DefStruct(node1) => defStructAnnotatedNode(in, (pre, node1, post))
case Ast.StateMachineMember.DefVector(node1) => defVectorAnnotatedNode(in, (pre, node1, post))
case Ast.StateMachineMember.SpecInclude(node1) => specIncludeAnnotatedNode(in, (pre, node1, post))
case Ast.StateMachineMember.SpecInitialTransition(node1) => specInitialTransitionAnnotatedNode(in, (pre, node1, post))
}
Expand Down
17 changes: 17 additions & 0 deletions compiler/lib/src/main/scala/codegen/AstWriter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,23 @@ object AstWriter extends AstVisitor with LineUtils {
).map(indentIn)
}

override def defVectorAnnotatedNode(
in: In,
aNode: Ast.Annotated[AstNode[Ast.DefVector]]
) = {
val (_, node, _) = aNode
val data = node.data
prefixWithDictionary("def vector", data.isDictionaryDef) ++
List.concat(
ident(data.name),
linesOpt(addPrefix("size prefix type", typeNameNode), data.sizePrefixType),
addPrefix("size", exprNode) (data.size),
typeNameNode(data.eltType),
linesOpt(addPrefix("default", exprNode), data.default),
linesOpt(addPrefix("format", applyToData(string)), data.format)
).map(indentIn)
}

override def defChoiceAnnotatedNode(
in: In,
aNode: Ast.Annotated[AstNode[Ast.DefChoice]]
Expand Down
21 changes: 21 additions & 0 deletions compiler/lib/src/main/scala/codegen/FppWriter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,27 @@ object FppWriter extends AstVisitor with LineUtils {
joinOpt (data.format) (" format ") (applyToData(string))
}

override def defVectorAnnotatedNode(
in: In,
aNode: Ast.Annotated[AstNode[Ast.DefVector]]
) = {
val (_, node, _) = aNode
val data = node.data
val start =
lines(prefixWithDictionary(s"vector ${ident(data.name)} = [", data.isDictionaryDef))
val withSize =
data.sizePrefixType match {
case Some(tn) =>
start.join ("") (typeNameNode(tn)).join (" size ") (exprNode(data.size))
case None =>
start.join ("size ") (exprNode(data.size))
}
withSize.
join ("] ") (typeNameNode(data.eltType)).
joinOpt (data.default) (" default ") (exprNode).
joinOpt (data.format) (" format ") (applyToData(string))
}

override def defChoiceAnnotatedNode(
in: In,
aNode: Ast.Annotated[AstNode[Ast.DefChoice]]
Expand Down
2 changes: 2 additions & 0 deletions compiler/lib/src/main/scala/syntax/Lexer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ object Lexer {
("type", TYPE),
("unmatched", UNMATCHED),
("update", UPDATE),
("vector", VECTOR),
("warning", WARNING),
("with", WITH),
("yellow", YELLOW)
Expand Down Expand Up @@ -359,6 +360,7 @@ object Lexer {
case U8 => Token.U8()
case UNMATCHED => Token.UNMATCHED()
case UPDATE => Token.UPDATE()
case VECTOR => Token.VECTOR()
case WARNING => Token.WARNING()
case WITH => Token.WITH()
case YELLOW => Token.YELLOW()
Expand Down
33 changes: 33 additions & 0 deletions compiler/lib/src/main/scala/syntax/Parser.scala
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ object Parser extends Parsers {
node(defStateMachine) ^^ (n =>
Ast.ComponentMember.DefStateMachine(n)) |
node(defStruct) ^^ (n => Ast.ComponentMember.DefStruct(n)) |
node(defVector) ^^ (n => Ast.ComponentMember.DefVector(n)) |
node(specCommand) ^^ (n => Ast.ComponentMember.SpecCommand(n)) |
node(specContainer) ^^ (n =>
Ast.ComponentMember.SpecContainer(n)) |
Expand Down Expand Up @@ -101,6 +102,34 @@ object Parser extends Parsers {
}
}

def defVector: Parser[Ast.DefVector] = {
opt(dictionary) ~ (vector ~>! ident <~! equals) ~!
vectorSize ~! node(typeName) ~!
opt(default ~>! exprNode) ~!
opt(format ~>! node(literalString)) ^^ {
case dictionary ~ name ~ vectorSize ~ eltType ~ default ~ format =>
val (size, sizePrefixType) = vectorSize
Ast.DefVector(
name,
size,
sizePrefixType,
eltType,
default,
format,
dictionary.isDefined
)
}
}

/** Parses a vector size specifier of the form `[` [ _type-name_ ] `size`
* _expression_ `]`. Returns the maximum-size expression and the optional
* size-prefix type. */
def vectorSize: Parser[(AstNode[Ast.Expr], Option[AstNode[Ast.TypeName]])] = {
lbracket ~>! (opt(node(typeName)) ~ (size ~>! exprNode)) <~! rbracket ^^ {
case sizePrefixType ~ size => (size, sizePrefixType)
}
}

private def defChoice: Parser[Ast.DefChoice] = {
(choice ~> ident) ~! (lbrace ~> ifToken ~> node(ident)) ~! node(
transitionExpr
Expand Down Expand Up @@ -452,6 +481,7 @@ object Parser extends Parsers {
node(defStruct) ^^ (n => Ast.ModuleMember.DefStruct(n)) |
node(defSystem) ^^ (n => Ast.ModuleMember.DefSystem(n)) |
node(defTopology) ^^ (n => Ast.ModuleMember.DefTopology(n)) |
node(defVector) ^^ (n => Ast.ModuleMember.DefVector(n)) |
node(specInclude) ^^ (n => Ast.ModuleMember.SpecInclude(n)) |
node(specLoc) ^^ (n => Ast.ModuleMember.SpecLoc(n)) |
failure("module member expected")
Expand Down Expand Up @@ -909,6 +939,7 @@ object Parser extends Parsers {
node(defSignal) ^^ (n => Ast.StateMachineMember.DefSignal(n)) |
node(defState) ^^ (n => Ast.StateMachineMember.DefState(n)) |
node(defStruct) ^^ (n => Ast.StateMachineMember.DefStruct(n)) |
node(defVector) ^^ (n => Ast.StateMachineMember.DefVector(n)) |
node(specInclude) ^^ (n => Ast.StateMachineMember.SpecInclude(n)) |
node(specInitialTransition) ^^ (n => Ast.StateMachineMember.SpecInitialTransition(n)) |
failure("state machine member expected")
Expand Down Expand Up @@ -1365,6 +1396,8 @@ object Parser extends Parsers {

private def update = accept("update", { case t: Token.UPDATE => t })

private def vector = accept("vector", { case t: Token.VECTOR => t })

private def warning = accept("warning", { case t: Token.WARNING => t })

private def yellow = accept("yellow", { case t: Token.YELLOW => t })
Expand Down
2 changes: 2 additions & 0 deletions compiler/lib/src/main/scala/syntax/Token.scala
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ object Token {
final case class U8() extends Token
final case class UNMATCHED() extends Token
final case class UPDATE() extends Token
final case class VECTOR() extends Token
final case class WARNING() extends Token
final case class WITH() extends Token
final case class YELLOW() extends Token
Expand Down Expand Up @@ -279,6 +280,7 @@ enum TokenId {
case U8
case UNMATCHED
case UPDATE
case VECTOR
case WARNING
case WITH
case YELLOW
Expand Down
30 changes: 30 additions & 0 deletions compiler/lib/src/test/scala/syntax/Parser.scala
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,36 @@ class ParserSpec extends AnyWordSpec {
)
}

"def vector OK" should {
parseAllOK(
Parser.defVector,
List(
"vector v = [size 10] U32",
"vector v = [size 10] U32 default [ 1, 2 ]",
"vector v = [size 10] U32 default [ 1, 2 ] format \"{} counts\"",
"vector v = [U16 size 10] U32",
"vector v = [a.b.C size 10] U32",
"dictionary vector v = [U8 size 10] U32"
)
)
}

"def vector error" should {
parseAllError(
Parser.defVector,
List(
// Missing the size keyword
"vector v = [10] U32",
// Missing the size expression
"vector v = [size] U32",
// Size-prefix type without the size keyword
"vector v = [U16 10] U32",
// Size-prefix type with missing size expression
"vector v = [U16 size] U32"
)
)
}

"def component OK" should {
parseAllOK(
Parser.defComponent,
Expand Down
9 changes: 9 additions & 0 deletions compiler/tools/fpp-format/test/include.ref.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,15 @@ module DefinitionsAndSpecifiers {
@ Array definition
array A = [10] U32 default 0 format "{} counts" @< Array definition

@ Vector definition with default size-prefix type
vector V = [size 10] U32 @< Vector definition with default size-prefix type

@ Vector definition with explicit size-prefix type
vector W = [U16 size 10] U32 default [
1
2
] format "{} counts" @< Vector definition with explicit size-prefix type

@ State machine outside a component
state machine SO @< State machine outside a component

Expand Down
9 changes: 9 additions & 0 deletions compiler/tools/fpp-format/test/no_include.ref.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,15 @@ module DefinitionsAndSpecifiers {
@ Array definition
array A = [10] U32 default 0 format "{} counts" @< Array definition

@ Vector definition with default size-prefix type
vector V = [size 10] U32 @< Vector definition with default size-prefix type

@ Vector definition with explicit size-prefix type
vector W = [U16 size 10] U32 default [
1
2
] format "{} counts" @< Vector definition with explicit size-prefix type

@ State machine outside a component
state machine SO @< State machine outside a component

Expand Down
17 changes: 17 additions & 0 deletions compiler/tools/fpp-syntax/test/syntax-ast.ref.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,23 @@ def module
default literal int 0
format {} counts
@< Array definition
@ Vector definition with default size-prefix type
def vector
ident V
size literal int 10
type name U32
@< Vector definition with default size-prefix type
@ Vector definition with explicit size-prefix type
def vector
ident W
size prefix type type name U16
size literal int 10
type name U32
default expr array
literal int 1
literal int 2
format {} counts
@< Vector definition with explicit size-prefix type
@ State machine outside a component
def state machine
ident SO
Expand Down
17 changes: 17 additions & 0 deletions compiler/tools/fpp-syntax/test/syntax-include-ast.ref.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,23 @@ def module
default literal int 0
format {} counts
@< Array definition
@ Vector definition with default size-prefix type
def vector
ident V
size literal int 10
type name U32
@< Vector definition with default size-prefix type
@ Vector definition with explicit size-prefix type
def vector
ident W
size prefix type type name U16
size literal int 10
type name U32
default expr array
literal int 1
literal int 2
format {} counts
@< Vector definition with explicit size-prefix type
@ State machine outside a component
def state machine
ident SO
Expand Down
Loading
Loading