Compare commits
5 Commits
297288e2b0
...
6908d9a91d
| Author | SHA1 | Date | |
|---|---|---|---|
| 6908d9a91d | |||
| 6882a32858 | |||
| 3ee1eab2f8 | |||
| d2797e1acc | |||
| 4f6de341cc |
@@ -43,6 +43,8 @@ public struct CompilerContext {
|
|||||||
public let ffis: [P4FFI]
|
public let ffis: [P4FFI]
|
||||||
public let expected_type: P4QualifiedType?
|
public let expected_type: P4QualifiedType?
|
||||||
public let extern_context: Bool
|
public let extern_context: Bool
|
||||||
|
public let lexical_context_name: Identifier?
|
||||||
|
public let lexical_context_statements: [P4Statement]?
|
||||||
|
|
||||||
public init() {
|
public init() {
|
||||||
instances = StaticVarValueScopes().enter()
|
instances = StaticVarValueScopes().enter()
|
||||||
@@ -51,6 +53,8 @@ public struct CompilerContext {
|
|||||||
expected_type = .none
|
expected_type = .none
|
||||||
extern_context = false
|
extern_context = false
|
||||||
ffis = Array()
|
ffis = Array()
|
||||||
|
lexical_context_name = .none
|
||||||
|
lexical_context_statements = .none
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(withInstances _instances: StaticVarValueScopes, withTypes _types: TypeTypeScopes) {
|
public init(withInstances _instances: StaticVarValueScopes, withTypes _types: TypeTypeScopes) {
|
||||||
@@ -60,12 +64,16 @@ public struct CompilerContext {
|
|||||||
expected_type = .none
|
expected_type = .none
|
||||||
extern_context = false
|
extern_context = false
|
||||||
ffis = Array()
|
ffis = Array()
|
||||||
|
lexical_context_name = .none
|
||||||
|
lexical_context_statements = .none
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(
|
public init(
|
||||||
withInstances _instances: StaticVarValueScopes, withTypes _types: TypeTypeScopes,
|
withInstances _instances: StaticVarValueScopes, withTypes _types: TypeTypeScopes,
|
||||||
withExpectation expectation: P4QualifiedType?, withExtern extern: Bool,
|
withExpectation expectation: P4QualifiedType?, withExtern extern: Bool,
|
||||||
withExterns externs: TypeTypeScopes, withFFIs foreigns: [P4FFI]
|
withExterns externs: TypeTypeScopes, withFFIs foreigns: [P4FFI],
|
||||||
|
withLexicalContextName lexical_context_name: Identifier?,
|
||||||
|
withLexicalContextStatements lexical_context_statements: [P4Statement]?
|
||||||
) {
|
) {
|
||||||
instances = _instances
|
instances = _instances
|
||||||
types = _types
|
types = _types
|
||||||
@@ -73,6 +81,8 @@ public struct CompilerContext {
|
|||||||
extern_context = extern
|
extern_context = extern
|
||||||
self.externs = externs
|
self.externs = externs
|
||||||
ffis = foreigns
|
ffis = foreigns
|
||||||
|
self.lexical_context_name = lexical_context_name
|
||||||
|
self.lexical_context_statements = lexical_context_statements
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Update a compiler context
|
/// Update a compiler context
|
||||||
@@ -84,7 +94,9 @@ public struct CompilerContext {
|
|||||||
public func update(newInstances instances: StaticVarValueScopes) -> CompilerContext {
|
public func update(newInstances instances: StaticVarValueScopes) -> CompilerContext {
|
||||||
return CompilerContext(
|
return CompilerContext(
|
||||||
withInstances: instances, withTypes: self.types, withExpectation: self.expected_type,
|
withInstances: instances, withTypes: self.types, withExpectation: self.expected_type,
|
||||||
withExtern: self.extern_context, withExterns: self.externs, withFFIs: self.ffis)
|
withExtern: self.extern_context, withExterns: self.externs, withFFIs: self.ffis,
|
||||||
|
withLexicalContextName: self.lexical_context_name,
|
||||||
|
withLexicalContextStatements: self.lexical_context_statements)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Update a compiler context
|
/// Update a compiler context
|
||||||
@@ -96,7 +108,9 @@ public struct CompilerContext {
|
|||||||
public func update(newTypes types: TypeTypeScopes) -> CompilerContext {
|
public func update(newTypes types: TypeTypeScopes) -> CompilerContext {
|
||||||
return CompilerContext(
|
return CompilerContext(
|
||||||
withInstances: self.instances, withTypes: types, withExpectation: self.expected_type,
|
withInstances: self.instances, withTypes: types, withExpectation: self.expected_type,
|
||||||
withExtern: self.extern_context, withExterns: self.externs, withFFIs: self.ffis)
|
withExtern: self.extern_context, withExterns: self.externs, withFFIs: self.ffis,
|
||||||
|
withLexicalContextName: self.lexical_context_name,
|
||||||
|
withLexicalContextStatements: self.lexical_context_statements)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Update a compiler context
|
/// Update a compiler context
|
||||||
@@ -108,7 +122,9 @@ public struct CompilerContext {
|
|||||||
public func update(newExpectation expectation: P4QualifiedType?) -> CompilerContext {
|
public func update(newExpectation expectation: P4QualifiedType?) -> CompilerContext {
|
||||||
return CompilerContext(
|
return CompilerContext(
|
||||||
withInstances: self.instances, withTypes: self.types, withExpectation: expectation,
|
withInstances: self.instances, withTypes: self.types, withExpectation: expectation,
|
||||||
withExtern: self.extern_context, withExterns: self.externs, withFFIs: self.ffis)
|
withExtern: self.extern_context, withExterns: self.externs, withFFIs: self.ffis,
|
||||||
|
withLexicalContextName: self.lexical_context_name,
|
||||||
|
withLexicalContextStatements: self.lexical_context_statements)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Update a compiler context
|
/// Update a compiler context
|
||||||
@@ -120,7 +136,9 @@ public struct CompilerContext {
|
|||||||
public func update(newExtern extern: Bool) -> CompilerContext {
|
public func update(newExtern extern: Bool) -> CompilerContext {
|
||||||
return CompilerContext(
|
return CompilerContext(
|
||||||
withInstances: self.instances, withTypes: self.types, withExpectation: self.expected_type,
|
withInstances: self.instances, withTypes: self.types, withExpectation: self.expected_type,
|
||||||
withExtern: extern, withExterns: self.externs, withFFIs: self.ffis)
|
withExtern: extern, withExterns: self.externs, withFFIs: self.ffis,
|
||||||
|
withLexicalContextName: self.lexical_context_name,
|
||||||
|
withLexicalContextStatements: self.lexical_context_statements)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Update a compiler context
|
/// Update a compiler context
|
||||||
@@ -132,7 +150,9 @@ public struct CompilerContext {
|
|||||||
public func update(newExterns externs: TypeTypeScopes) -> CompilerContext {
|
public func update(newExterns externs: TypeTypeScopes) -> CompilerContext {
|
||||||
return CompilerContext(
|
return CompilerContext(
|
||||||
withInstances: self.instances, withTypes: self.types, withExpectation: self.expected_type,
|
withInstances: self.instances, withTypes: self.types, withExpectation: self.expected_type,
|
||||||
withExtern: self.extern_context, withExterns: externs, withFFIs: self.ffis)
|
withExtern: self.extern_context, withExterns: externs, withFFIs: self.ffis,
|
||||||
|
withLexicalContextName: self.lexical_context_name,
|
||||||
|
withLexicalContextStatements: self.lexical_context_statements)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Update a compiler context
|
/// Update a compiler context
|
||||||
@@ -144,6 +164,40 @@ public struct CompilerContext {
|
|||||||
public func update(newFFIs foreigns: [P4FFI]) -> CompilerContext {
|
public func update(newFFIs foreigns: [P4FFI]) -> CompilerContext {
|
||||||
return CompilerContext(
|
return CompilerContext(
|
||||||
withInstances: self.instances, withTypes: self.types, withExpectation: self.expected_type,
|
withInstances: self.instances, withTypes: self.types, withExpectation: self.expected_type,
|
||||||
withExtern: self.extern_context, withExterns: externs, withFFIs: foreigns)
|
withExtern: self.extern_context, withExterns: externs, withFFIs: foreigns,
|
||||||
|
withLexicalContextName: self.lexical_context_name,
|
||||||
|
withLexicalContextStatements: self.lexical_context_statements)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Update a compiler context
|
||||||
|
///
|
||||||
|
/// Create a new compiler context based on the current but with a new lexical context name.
|
||||||
|
///
|
||||||
|
/// - Parameter new_lexical_context_name: an optional new lexical context name; passing `.none` resets.
|
||||||
|
/// - Returns: A new compiler context based on the current but with a new lexical context name.
|
||||||
|
public func update(newLexicalContextName new_lexical_context_name: Identifier?) -> CompilerContext
|
||||||
|
{
|
||||||
|
return CompilerContext(
|
||||||
|
withInstances: self.instances, withTypes: self.types, withExpectation: self.expected_type,
|
||||||
|
withExtern: self.extern_context, withExterns: externs, withFFIs: self.ffis,
|
||||||
|
withLexicalContextName: new_lexical_context_name,
|
||||||
|
withLexicalContextStatements: self.lexical_context_statements)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Update a compiler context
|
||||||
|
///
|
||||||
|
/// Create a new compiler context based on the current but with a new set of lexical context statements.
|
||||||
|
///
|
||||||
|
/// - Parameter new_lexical_context_statements: an optional new set of lexical context statements; passing `.none` resets.
|
||||||
|
/// - Returns: A new compiler context based on the current but with a new set of lexical context statements.
|
||||||
|
public func update(
|
||||||
|
newLexicalContextStatements new_lexical_context_statements: [P4Statement]?
|
||||||
|
) -> CompilerContext {
|
||||||
|
return CompilerContext(
|
||||||
|
withInstances: self.instances, withTypes: self.types, withExpectation: self.expected_type,
|
||||||
|
withExtern: self.extern_context, withExterns: externs, withFFIs: self.ffis,
|
||||||
|
withLexicalContextName: self.lexical_context_name,
|
||||||
|
withLexicalContextStatements: new_lexical_context_statements)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -106,6 +106,3 @@ public func Fold<T, A>(input: [T], initial: A, block: (T, A) -> A) -> A {
|
|||||||
|
|
||||||
@freestanding(codeItem) public macro MustOr<E, N>(result: E, thing: E?, or: N) =
|
@freestanding(codeItem) public macro MustOr<E, N>(result: E, thing: E?, or: N) =
|
||||||
#externalMacro(module: "Macros", type: "MustOr")
|
#externalMacro(module: "Macros", type: "MustOr")
|
||||||
|
|
||||||
@attached(peer) public macro DeriveCompilableStatement() =
|
|
||||||
#externalMacro(module: "Macros", type: "DeriveCompilableStatement")
|
|
||||||
|
|||||||
@@ -439,17 +439,14 @@ public struct CliTestDeclarationMacro: PeerMacro, Sendable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct DeriveCompilableStatement: PeerMacro, Sendable {
|
public enum DeriveCompilableStatement: MemberMacro {
|
||||||
public static func expansion(
|
public static func expansion(
|
||||||
of node: AttributeSyntax,
|
of: AttributeSyntax, providingMembersOf type: some DeclGroupSyntax, conformingTo: [TypeSyntax],
|
||||||
providingPeersOf declaration: some DeclSyntaxProtocol,
|
in: some MacroExpansionContext
|
||||||
in context: some MacroExpansionContext
|
|
||||||
) throws -> [DeclSyntax] {
|
) throws -> [DeclSyntax] {
|
||||||
|
|
||||||
let type_name = declaration.cast(ExtensionDeclSyntax.self).extendedType
|
|
||||||
let implementation = DeclSyntax(
|
let implementation = DeclSyntax(
|
||||||
"""
|
"""
|
||||||
extension VariableDeclarationStatement: CompilableStatement {
|
|
||||||
public static func CompileStatement(
|
public static func CompileStatement(
|
||||||
node: Node, withContext context: CompilerContext
|
node: Node, withContext context: CompilerContext
|
||||||
) -> Result<P4Statement> {
|
) -> Result<P4Statement> {
|
||||||
@@ -458,7 +455,6 @@ public struct DeriveCompilableStatement: PeerMacro, Sendable {
|
|||||||
case .Error(let e): .Error(e)
|
case .Error(let e): .Error(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
""")
|
""")
|
||||||
return [implementation]
|
return [implementation]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -384,3 +384,7 @@ extension Node {
|
|||||||
return SourceLocation(self.range.location, self.range.length)
|
return SourceLocation(self.range.location, self.range.length)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@attached(member, names: named(CompileStatement))
|
||||||
|
public macro deriveCompilableStatement() =
|
||||||
|
#externalMacro(module: "Macros", type: "DeriveCompilableStatement")
|
||||||
|
|||||||
@@ -81,8 +81,6 @@ extension FunctionDeclaration: Compilable {
|
|||||||
nice_type_name: "Function Declaration")
|
nice_type_name: "Function Declaration")
|
||||||
|
|
||||||
var walker = Walker(node: function_declaration_node)
|
var walker = Walker(node: function_declaration_node)
|
||||||
var context = context
|
|
||||||
|
|
||||||
var current_node: Node? = .none
|
var current_node: Node? = .none
|
||||||
|
|
||||||
#MustOr(
|
#MustOr(
|
||||||
@@ -224,16 +222,14 @@ extension P4Struct: Compilable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var parse_errs: (any Errorable)? = .none
|
var parse_errs: (any Errorable)? = .none
|
||||||
var current_context = context
|
|
||||||
var parsed_fields: [P4StructFieldIdentifier] = Array()
|
var parsed_fields: [P4StructFieldIdentifier] = Array()
|
||||||
|
|
||||||
if currentNode!.nodeType == "struct_declaration_fields" {
|
if currentNode!.nodeType == "struct_declaration_fields" {
|
||||||
currentNode!.enumerateNamedChildren { declaration_field in
|
currentNode!.enumerateNamedChildren { declaration_field in
|
||||||
switch VariableDeclarationStatement.Compile(
|
switch VariableDeclarationStatement.Compile(
|
||||||
node: declaration_field, withContext: current_context)
|
node: declaration_field, withContext: context)
|
||||||
{
|
{
|
||||||
case .Ok(let declaration):
|
case .Ok(let variable_declaration):
|
||||||
let variable_declaration = declaration as! VariableDeclarationStatement
|
|
||||||
parsed_fields.append(
|
parsed_fields.append(
|
||||||
P4StructFieldIdentifier(
|
P4StructFieldIdentifier(
|
||||||
id: variable_declaration.identifier, withType: variable_declaration.initializer.type()
|
id: variable_declaration.identifier, withType: variable_declaration.initializer.type()
|
||||||
@@ -393,7 +389,7 @@ extension P4Lang.Parser: Compilable {
|
|||||||
withName: parser_name!, withParameters: parameter_list, node: current_node!,
|
withName: parser_name!, withParameters: parameter_list, node: current_node!,
|
||||||
withContext: current_context)
|
withContext: current_context)
|
||||||
{
|
{
|
||||||
case Result.Ok((let parser, let updated_context)):
|
case Result.Ok(let parser):
|
||||||
let parser_declaration = Declaration(
|
let parser_declaration = Declaration(
|
||||||
TypedIdentifier(id: parser.name, withType: P4QualifiedType(parser)))
|
TypedIdentifier(id: parser.name, withType: P4QualifiedType(parser)))
|
||||||
// Create a new context with the name of the parser that was just compiled in scope.
|
// Create a new context with the name of the parser that was just compiled in scope.
|
||||||
@@ -507,7 +503,7 @@ extension Control: Compilable {
|
|||||||
else {
|
else {
|
||||||
return .Error(maybe_apply_statement.error()!)
|
return .Error(maybe_apply_statement.error()!)
|
||||||
}
|
}
|
||||||
apply = (apply_statement as! ApplyStatement)
|
apply = apply_statement
|
||||||
|
|
||||||
// The apply is the last thing in a control declaration.
|
// The apply is the last thing in a control declaration.
|
||||||
// But, that is handled by the compiler.
|
// But, that is handled by the compiler.
|
||||||
@@ -570,7 +566,6 @@ extension Action: Compilable {
|
|||||||
|
|
||||||
var walker = Walker(node: node)
|
var walker = Walker(node: node)
|
||||||
var current_node: Node? = .none
|
var current_node: Node? = .none
|
||||||
var current_context = context
|
|
||||||
|
|
||||||
// Skip action keyword
|
// Skip action keyword
|
||||||
walker.next()
|
walker.next()
|
||||||
@@ -585,7 +580,7 @@ extension Action: Compilable {
|
|||||||
|
|
||||||
guard
|
guard
|
||||||
case .Ok(let action_name) = Identifier.Compile(
|
case .Ok(let action_name) = Identifier.Compile(
|
||||||
node: current_node!, withContext: current_context)
|
node: current_node!, withContext: context)
|
||||||
else {
|
else {
|
||||||
return Result.Error(
|
return Result.Error(
|
||||||
Error(withMessage: "Could not parse an action name from \(current_node!.text!)"))
|
Error(withMessage: "Could not parse an action name from \(current_node!.text!)"))
|
||||||
@@ -601,7 +596,7 @@ extension Action: Compilable {
|
|||||||
)
|
)
|
||||||
|
|
||||||
let maybe_action_parameters = ParameterList.Compile(
|
let maybe_action_parameters = ParameterList.Compile(
|
||||||
node: current_node!, withContext: current_context)
|
node: current_node!, withContext: context)
|
||||||
guard case .Ok(let action_parameters) = maybe_action_parameters
|
guard case .Ok(let action_parameters) = maybe_action_parameters
|
||||||
else {
|
else {
|
||||||
return .Error(maybe_action_parameters.error()!)
|
return .Error(maybe_action_parameters.error()!)
|
||||||
@@ -645,7 +640,7 @@ extension Action: Compilable {
|
|||||||
return .Ok(
|
return .Ok(
|
||||||
Action(
|
Action(
|
||||||
named: action_name, withParameters: action_parameters,
|
named: action_name, withParameters: action_parameters,
|
||||||
withBody: (action_body as! BlockStatement)))
|
withBody: action_body))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -662,8 +657,6 @@ extension TableKeyEntry: Compilable {
|
|||||||
|
|
||||||
var current_node: Node? = .none
|
var current_node: Node? = .none
|
||||||
|
|
||||||
let current_context = context
|
|
||||||
|
|
||||||
#MustOr(
|
#MustOr(
|
||||||
result: current_node, thing: walker.getNext(),
|
result: current_node, thing: walker.getNext(),
|
||||||
or: Result<TableKeyEntry>.Error(
|
or: Result<TableKeyEntry>.Error(
|
||||||
@@ -672,7 +665,7 @@ extension TableKeyEntry: Compilable {
|
|||||||
withError: "Missing table key entry declaration component")))
|
withError: "Missing table key entry declaration component")))
|
||||||
|
|
||||||
let maybe_keyset_expression = KeysetExpression.compile(
|
let maybe_keyset_expression = KeysetExpression.compile(
|
||||||
node: current_node!, withContext: current_context)
|
node: current_node!, withContext: context)
|
||||||
guard case .Ok(let keyset_expression) = maybe_keyset_expression else {
|
guard case .Ok(let keyset_expression) = maybe_keyset_expression else {
|
||||||
return Result.Error(maybe_keyset_expression.error()!)
|
return Result.Error(maybe_keyset_expression.error()!)
|
||||||
}
|
}
|
||||||
@@ -688,7 +681,7 @@ extension TableKeyEntry: Compilable {
|
|||||||
withError: "Missing table key entry declaration component")))
|
withError: "Missing table key entry declaration component")))
|
||||||
|
|
||||||
let maybe_match_type = TableKeyMatchType.Compile(
|
let maybe_match_type = TableKeyMatchType.Compile(
|
||||||
node: current_node!, withContext: current_context)
|
node: current_node!, withContext: context)
|
||||||
guard case .Ok(let match_type) = maybe_match_type else {
|
guard case .Ok(let match_type) = maybe_match_type else {
|
||||||
return .Error(maybe_match_type.error()!)
|
return .Error(maybe_match_type.error()!)
|
||||||
}
|
}
|
||||||
@@ -829,21 +822,19 @@ extension TablePropertyList: Compilable {
|
|||||||
#RequireNodeType<Node, TablePropertyList>(
|
#RequireNodeType<Node, TablePropertyList>(
|
||||||
node: node, type: "table_property_list", nice_type_name: "Table Property List")
|
node: node, type: "table_property_list", nice_type_name: "Table Property List")
|
||||||
|
|
||||||
var current_context = context
|
|
||||||
|
|
||||||
var keys: [TableKeys] = Array()
|
var keys: [TableKeys] = Array()
|
||||||
var actions: [TableActionsProperty] = Array()
|
var actions: [TableActionsProperty] = Array()
|
||||||
var errors: [any Errorable] = Array()
|
var errors: [any Errorable] = Array()
|
||||||
|
|
||||||
node.enumerateNamedChildren { child in
|
node.enumerateNamedChildren { child in
|
||||||
if child.nodeType == "table_keys" {
|
if child.nodeType == "table_keys" {
|
||||||
switch TableKeys.Compile(node: child, withContext: current_context) {
|
switch TableKeys.Compile(node: child, withContext: context) {
|
||||||
case .Ok(let table_key):
|
case .Ok(let table_key):
|
||||||
keys.append(table_key)
|
keys.append(table_key)
|
||||||
case .Error(let e): errors.append(e)
|
case .Error(let e): errors.append(e)
|
||||||
}
|
}
|
||||||
} else if child.nodeType == "table_actions" {
|
} else if child.nodeType == "table_actions" {
|
||||||
switch TableActionsProperty.Compile(node: child, withContext: current_context) {
|
switch TableActionsProperty.Compile(node: child, withContext: context) {
|
||||||
case .Ok(let table_action_property):
|
case .Ok(let table_action_property):
|
||||||
actions.append(table_action_property)
|
actions.append(table_action_property)
|
||||||
case .Error(let e): errors.append(e)
|
case .Error(let e): errors.append(e)
|
||||||
@@ -906,8 +897,6 @@ extension Table: Compilable {
|
|||||||
|
|
||||||
var current_node: Node? = .none
|
var current_node: Node? = .none
|
||||||
|
|
||||||
let current_context = context
|
|
||||||
|
|
||||||
walker.next() // Skip the XXX?
|
walker.next() // Skip the XXX?
|
||||||
#MustOr(
|
#MustOr(
|
||||||
result: current_node, thing: walker.getNext(),
|
result: current_node, thing: walker.getNext(),
|
||||||
@@ -918,7 +907,7 @@ extension Table: Compilable {
|
|||||||
|
|
||||||
guard
|
guard
|
||||||
case .Ok(let table_name) = Identifier.Compile(
|
case .Ok(let table_name) = Identifier.Compile(
|
||||||
node: current_node!, withContext: current_context)
|
node: current_node!, withContext: context)
|
||||||
else {
|
else {
|
||||||
return Result.Error(
|
return Result.Error(
|
||||||
Error(withMessage: "Could not parse a table name from \(current_node!.text!)"))
|
Error(withMessage: "Could not parse a table name from \(current_node!.text!)"))
|
||||||
@@ -935,7 +924,7 @@ extension Table: Compilable {
|
|||||||
))
|
))
|
||||||
|
|
||||||
let maybe_table_property_list = TablePropertyList.Compile(
|
let maybe_table_property_list = TablePropertyList.Compile(
|
||||||
node: current_node!, withContext: current_context)
|
node: current_node!, withContext: context)
|
||||||
guard case .Ok(let table_property_list) = maybe_table_property_list else {
|
guard case .Ok(let table_property_list) = maybe_table_property_list else {
|
||||||
return Result.Error(maybe_table_property_list.error()!)
|
return Result.Error(maybe_table_property_list.error()!)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -178,8 +178,9 @@ extension ParserState: Compilable {
|
|||||||
sourceLocation: node.toSourceLocation(),
|
sourceLocation: node.toSourceLocation(),
|
||||||
withError: "Missing transition statement of state declaration")))
|
withError: "Missing transition statement of state declaration")))
|
||||||
|
|
||||||
return SpecialCompilers.TransitionStatement.Compile(
|
let updated_context = SpecialCompilers.Statements.effect(statements: parsed_s, context: context)
|
||||||
node: current_node!, forState: state_identifier, withStatements: parsed_s,
|
.update(newLexicalContextName: state_identifier).update(newLexicalContextStatements: parsed_s)
|
||||||
withContext: SpecialCompilers.Statements.effect(statements: parsed_s, context: context))
|
|
||||||
|
return TransitionStatement.Compile(node: current_node!, withContext: updated_context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,88 +28,103 @@ protocol AnyCompilable {
|
|||||||
) -> Common.Result<(Any, CompilerContext)>
|
) -> Common.Result<(Any, CompilerContext)>
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct SpecialCompilers {
|
extension TransitionStatement: Compilable {
|
||||||
public struct TransitionStatement {
|
public static func Compile(
|
||||||
static func Compile(
|
node: Node, withContext context: CompilerContext
|
||||||
node: Node, forState state_identifier: Common.Identifier,
|
) -> Result<ParserState> {
|
||||||
withStatements stmts: [P4Statement], withContext context: CompilerContext
|
|
||||||
) -> Result<ParserState> {
|
|
||||||
|
|
||||||
#RequireNodeType<Node, P4Statement>(
|
guard let state_identifier = context.lexical_context_name else {
|
||||||
node: node, type: "parserTransitionStatement", nice_type_name: "parser transition statement"
|
return .Error(
|
||||||
)
|
ErrorWithLocation(
|
||||||
|
sourceLocation: node.toSourceLocation(),
|
||||||
|
withError: "Cannot parse a transition statement without the name of the containing state."
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
guard let tse_node = node.child(at: 1),
|
guard let stmts = context.lexical_context_statements else {
|
||||||
tse_node.nodeType! == "transitionSelectionExpression"
|
return .Error(
|
||||||
else {
|
ErrorWithLocation(
|
||||||
return .Error(
|
sourceLocation: node.toSourceLocation(),
|
||||||
ErrorWithLocation(
|
withError:
|
||||||
sourceLocation: node.toSourceLocation(),
|
"Cannot parse a transition statement without statements of the containing state."))
|
||||||
withError: "Could not find transition select expression"))
|
}
|
||||||
}
|
|
||||||
|
|
||||||
guard let next_node = tse_node.child(at: 0) else {
|
#RequireNodeType<Node, P4Statement>(
|
||||||
return .Error(
|
node: node, type: "parserTransitionStatement", nice_type_name: "parser transition statement"
|
||||||
ErrorWithLocation(
|
)
|
||||||
sourceLocation: node.toSourceLocation(),
|
|
||||||
withError: "Could not find the next token in a transition selection expression"))
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the next node is an identifier, we have the simple form ...
|
guard let tse_node = node.child(at: 1),
|
||||||
if next_node.nodeType == "identifier" {
|
tse_node.nodeType! == "transitionSelectionExpression"
|
||||||
let maybe_parsed_next_state_id = Identifier.Compile(
|
else {
|
||||||
node: next_node, withContext: context)
|
return .Error(
|
||||||
if case .Ok(let next_state_id) = maybe_parsed_next_state_id {
|
ErrorWithLocation(
|
||||||
if case .Ok(let next_state) = context.instances.lookup(identifier: next_state_id) {
|
sourceLocation: node.toSourceLocation(),
|
||||||
switch next_state {
|
withError: "Could not find transition select expression"))
|
||||||
case (_, .some(let instance)):
|
}
|
||||||
return .Ok(
|
|
||||||
ParserStateDirectTransition(
|
guard let next_node = tse_node.child(at: 0) else {
|
||||||
name: state_identifier,
|
return .Error(
|
||||||
withNextState: instance.dataValue() as! InstantiatedParserState,
|
ErrorWithLocation(
|
||||||
withStatements: stmts,
|
sourceLocation: node.toSourceLocation(),
|
||||||
)
|
withError: "Could not find the next token in a transition selection expression"))
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the next node is an identifier, we have the simple form ...
|
||||||
|
if next_node.nodeType == "identifier" {
|
||||||
|
let maybe_parsed_next_state_id = Identifier.Compile(
|
||||||
|
node: next_node, withContext: context)
|
||||||
|
if case .Ok(let next_state_id) = maybe_parsed_next_state_id {
|
||||||
|
if case .Ok(let next_state) = context.instances.lookup(identifier: next_state_id) {
|
||||||
|
switch next_state {
|
||||||
|
case (_, .some(let instance)):
|
||||||
|
return .Ok(
|
||||||
|
ParserStateDirectTransition(
|
||||||
|
name: state_identifier,
|
||||||
|
withNextState: instance.dataValue() as! InstantiatedParserState,
|
||||||
|
withStatements: stmts,
|
||||||
)
|
)
|
||||||
case (_, .none):
|
)
|
||||||
return .Ok(
|
case (_, .none):
|
||||||
ParserStateDirectTransition(
|
return .Ok(
|
||||||
name: state_identifier,
|
ParserStateDirectTransition(
|
||||||
withNextStateIdentifier: next_state_id, withStatements: stmts)
|
name: state_identifier,
|
||||||
)
|
withNextStateIdentifier: next_state_id, withStatements: stmts)
|
||||||
}
|
)
|
||||||
} else {
|
|
||||||
|
|
||||||
return .Error(
|
|
||||||
Error(
|
|
||||||
withMessage:
|
|
||||||
"\(next_state_id) does not name a parser state in scope"
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
return .Error(
|
return .Error(
|
||||||
Error(
|
Error(
|
||||||
withMessage:
|
withMessage:
|
||||||
"Could not parse the next state in a transition statement: \(maybe_parsed_next_state_id.error()!)"
|
"\(next_state_id) does not name a parser state in scope"
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
|
return .Error(
|
||||||
// We know that the next node is a select expression.
|
Error(
|
||||||
return
|
withMessage:
|
||||||
switch SelectExpression.compile(node: next_node, withContext: context)
|
"Could not parse the next state in a transition statement: \(maybe_parsed_next_state_id.error()!)"
|
||||||
{
|
))
|
||||||
case .Ok(let tse):
|
|
||||||
.Ok(
|
|
||||||
ParserStateSelectTransition(
|
|
||||||
name: state_identifier, withTransitionExpression: tse as! SelectExpression,
|
|
||||||
withStatements: stmts,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
case .Error(let e): .Error(e)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
// We know that the next node is a select expression.
|
||||||
|
return
|
||||||
|
switch SelectExpression.compile(node: next_node, withContext: context)
|
||||||
|
{
|
||||||
|
case .Ok(let tse):
|
||||||
|
.Ok(
|
||||||
|
ParserStateSelectTransition(
|
||||||
|
name: state_identifier, withTransitionExpression: tse as! SelectExpression,
|
||||||
|
withStatements: stmts,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
case .Error(let e): .Error(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct SpecialCompilers {
|
||||||
public struct Statements {
|
public struct Statements {
|
||||||
static func Compile(
|
static func Compile(
|
||||||
node: Node, withContext context: CompilerContext
|
node: Node, withContext context: CompilerContext
|
||||||
@@ -161,7 +176,7 @@ public struct SpecialCompilers {
|
|||||||
static func CompileParserBody(
|
static func CompileParserBody(
|
||||||
withName name: Common.Identifier, withParameters parameters: ParameterList, node: Node,
|
withName name: Common.Identifier, withParameters parameters: ParameterList, node: Node,
|
||||||
withContext context: CompilerContext
|
withContext context: CompilerContext
|
||||||
) -> Result<(P4Lang.Parser, CompilerContext)> {
|
) -> Result<P4Lang.Parser> {
|
||||||
|
|
||||||
var parser = P4Lang.Parser(withName: name, withParameters: parameters)
|
var parser = P4Lang.Parser(withName: name, withParameters: parameters)
|
||||||
|
|
||||||
@@ -192,7 +207,7 @@ public struct SpecialCompilers {
|
|||||||
return .Error(error)
|
return .Error(error)
|
||||||
}
|
}
|
||||||
|
|
||||||
return Result.Ok((parser, current_context))
|
return Result.Ok(parser)
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct ProgramCompiler {
|
public struct ProgramCompiler {
|
||||||
|
|||||||
@@ -90,16 +90,8 @@ extension BlockStatement: Compilable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension BlockStatement: CompilableStatement {
|
@deriveCompilableStatement
|
||||||
public static func CompileStatement(
|
extension BlockStatement: CompilableStatement {}
|
||||||
node: Node, withContext context: CompilerContext
|
|
||||||
) -> Result<P4Statement> {
|
|
||||||
return switch Compile(node: node, withContext: context) {
|
|
||||||
case .Ok(let res): .Ok(res)
|
|
||||||
case .Error(let e): .Error(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension ConditionalStatement: Compilable {
|
extension ConditionalStatement: Compilable {
|
||||||
public typealias C = ConditionalStatement
|
public typealias C = ConditionalStatement
|
||||||
@@ -173,16 +165,8 @@ extension ConditionalStatement: Compilable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension ConditionalStatement: CompilableStatement {
|
@deriveCompilableStatement
|
||||||
public static func CompileStatement(
|
extension ConditionalStatement: CompilableStatement {}
|
||||||
node: Node, withContext context: CompilerContext
|
|
||||||
) -> Result<P4Statement> {
|
|
||||||
return switch Compile(node: node, withContext: context) {
|
|
||||||
case .Ok(let res): .Ok(res)
|
|
||||||
case .Error(let e): .Error(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension VariableDeclarationStatement: Compilable {
|
extension VariableDeclarationStatement: Compilable {
|
||||||
public typealias C = VariableDeclarationStatement
|
public typealias C = VariableDeclarationStatement
|
||||||
@@ -279,16 +263,8 @@ extension VariableDeclarationStatement: Compilable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension VariableDeclarationStatement: CompilableStatement {
|
@deriveCompilableStatement
|
||||||
public static func CompileStatement(
|
extension VariableDeclarationStatement: CompilableStatement {}
|
||||||
node: Node, withContext context: CompilerContext
|
|
||||||
) -> Result<P4Statement> {
|
|
||||||
return switch Compile(node: node, withContext: context) {
|
|
||||||
case .Ok(let res): .Ok(res)
|
|
||||||
case .Error(let e): .Error(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension ExpressionStatement: Compilable {
|
extension ExpressionStatement: Compilable {
|
||||||
public typealias C = ExpressionStatement
|
public typealias C = ExpressionStatement
|
||||||
@@ -307,16 +283,8 @@ extension ExpressionStatement: Compilable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension ExpressionStatement: CompilableStatement {
|
@deriveCompilableStatement
|
||||||
public static func CompileStatement(
|
extension ExpressionStatement: CompilableStatement {}
|
||||||
node: Node, withContext context: CompilerContext
|
|
||||||
) -> Result<P4Statement> {
|
|
||||||
return switch Compile(node: node, withContext: context) {
|
|
||||||
case .Ok(let res): .Ok(res)
|
|
||||||
case .Error(let e): .Error(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension ParserAssignmentStatement: Compilable {
|
extension ParserAssignmentStatement: Compilable {
|
||||||
public typealias C = ParserAssignmentStatement
|
public typealias C = ParserAssignmentStatement
|
||||||
@@ -372,16 +340,8 @@ extension ParserAssignmentStatement: Compilable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension ParserAssignmentStatement: CompilableStatement {
|
@deriveCompilableStatement
|
||||||
public static func CompileStatement(
|
extension ParserAssignmentStatement: CompilableStatement {}
|
||||||
node: Node, withContext context: CompilerContext
|
|
||||||
) -> Result<P4Statement> {
|
|
||||||
return switch Compile(node: node, withContext: context) {
|
|
||||||
case .Ok(let res): .Ok(res)
|
|
||||||
case .Error(let e): .Error(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension ReturnStatement: Compilable {
|
extension ReturnStatement: Compilable {
|
||||||
public typealias C = ReturnStatement
|
public typealias C = ReturnStatement
|
||||||
@@ -410,16 +370,8 @@ extension ReturnStatement: Compilable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension ReturnStatement: CompilableStatement {
|
@deriveCompilableStatement
|
||||||
public static func CompileStatement(
|
extension ReturnStatement: CompilableStatement {}
|
||||||
node: Node, withContext context: CompilerContext
|
|
||||||
) -> Result<P4Statement> {
|
|
||||||
return switch Compile(node: node, withContext: context) {
|
|
||||||
case .Ok(let res): .Ok(res)
|
|
||||||
case .Error(let e): .Error(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension ApplyStatement: Compilable {
|
extension ApplyStatement: Compilable {
|
||||||
public typealias C = ApplyStatement
|
public typealias C = ApplyStatement
|
||||||
@@ -433,22 +385,14 @@ extension ApplyStatement: Compilable {
|
|||||||
|
|
||||||
return switch BlockStatement.Compile(node: expression_node, withContext: context) {
|
return switch BlockStatement.Compile(node: expression_node, withContext: context) {
|
||||||
case .Ok(let statement):
|
case .Ok(let statement):
|
||||||
.Ok(ApplyStatement(statement as! BlockStatement))
|
.Ok(ApplyStatement(statement))
|
||||||
case .Error(let e): .Error(e)
|
case .Error(let e): .Error(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension ApplyStatement: CompilableStatement {
|
@deriveCompilableStatement
|
||||||
public static func CompileStatement(
|
extension ApplyStatement: CompilableStatement {}
|
||||||
node: Node, withContext context: CompilerContext
|
|
||||||
) -> Result<P4Statement> {
|
|
||||||
return switch Compile(node: node, withContext: context) {
|
|
||||||
case .Ok(let res): .Ok(res)
|
|
||||||
case .Error(let e): .Error(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension Instantiation: Compilable {
|
extension Instantiation: Compilable {
|
||||||
public typealias C = Instantiation
|
public typealias C = Instantiation
|
||||||
@@ -582,13 +526,5 @@ extension Instantiation: Compilable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension Instantiation: CompilableStatement {
|
@deriveCompilableStatement
|
||||||
public static func CompileStatement(
|
extension Instantiation: CompilableStatement {}
|
||||||
node: Node, withContext context: CompilerContext
|
|
||||||
) -> Result<P4Statement> {
|
|
||||||
return switch Compile(node: node, withContext: context) {
|
|
||||||
case .Ok(let res): .Ok(res)
|
|
||||||
case .Error(let e): .Error(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user