Skip to content

Commit

Permalink
progress
Browse files Browse the repository at this point in the history
  • Loading branch information
Nimaoth committed Dec 20, 2023
1 parent ef16a2b commit 4d0f699
Show file tree
Hide file tree
Showing 10 changed files with 134 additions and 49 deletions.
2 changes: 1 addition & 1 deletion model/cell-builder.ast-model

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion model/test-language-playground.ast-model
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"id":"83ffffff498d873d63c0237c","languages":["654fbb281446e19b38225240"],"models":[],"rootNodes":[{"id":"83ffffff3ad25b0d1f366101","class":"83ffffffc5a5c4772047375d","children":[["83ffffffc5a5c47720473a16",[{"id":"83ffffffa9e6fd006c2f6560","class":"83ffffffdac33e2a035f09f5","properties":[["83ffffffdac33e2a035f0b9f","123"]]},{"id":"84ffffff387fcb48481a0cb2","class":"84ffffff9a22d56250a12369","properties":[["84ffffff9a22d56250a126ff","abc"]],"children":[["84ffffffacef843b710598dc",[{"id":"84ffffff387fcb48481a0cd0","class":"83ffffffdac33e2a035f09f5","properties":[["83ffffffdac33e2a035f0b9f","123"]]}]]]},{"id":"84ffffff2fdc090e013fa4d8","class":"84ffffff9a22d56250a12ae3","references":[["84ffffff9a22d56250a12d69","000000000000000000000000"]]},{"id":"83ffffffb3802c0151db830f","class":"83ffffffdac33e2a035f07f3","children":[["83ffffffdac33e2a035f0129",[{"id":"83ffffffb3802c0151db831b","class":"83ffffffdac33e2a035f09f5","properties":[["83ffffffdac33e2a035f0b9f","456"]]}]],["83ffffffdac33e2a035f028e",[{"id":"83ffffffb3802c0151db8347","class":"83ffffffdac33e2a035f09f5","properties":[["83ffffffdac33e2a035f0b9f","951"]]}]]]},{"id":"83ffffffb3802c0151db8368","class":"83ffffffdac33e2a035f07f3","children":[["83ffffffdac33e2a035f0129",[{"id":"83ffffffb3802c0151db8378","class":"83ffffffdac33e2a035f09f5","properties":[["83ffffffdac33e2a035f0b9f","123"]]}]],["83ffffffdac33e2a035f028e",[{"id":"83ffffffb3802c0151db838e","class":"83ffffffc5a5c4772047375d","children":[["83ffffffc5a5c47720473a16",[{"id":"83ffffffb3802c0151db83a2","class":"83ffffffdac33e2a035f09f5","properties":[["83ffffffdac33e2a035f0b9f","789"]]}]]]}]]]}]]]}]}
{"id":"83ffffff498d873d63c0237c","languages":["654fbb281446e19b38225240"],"models":[],"rootNodes":[{"id":"83ffffff3ad25b0d1f366101","class":"83ffffffc5a5c4772047375d","children":[["83ffffffc5a5c47720473a16",[{"id":"83ffffffa9e6fd006c2f6560","class":"83ffffffdac33e2a035f09f5","properties":[["83ffffffdac33e2a035f0b9f","123"]]},{"id":"84ffffffe801a7387cb63efc","class":"84ffffff9a22d56250a12369","properties":[["62e5339c564d29f772934529","a"]],"children":[["84ffffffacef843b710598dc",[{"id":"84ffffff8ded04333b862084","class":"83ffffffdac33e2a035f09f5","properties":[["83ffffffdac33e2a035f0b9f","123"]]}]]]},{"id":"84ffffff721514785141d162","class":"84ffffff9a22d56250a12369","properties":[["62e5339c564d29f772934529","b"]],"children":[["84ffffffacef843b710598dc",[{"id":"84ffffff721514785141d182","class":"83ffffffdac33e2a035f09f5","properties":[["83ffffffdac33e2a035f0b9f","456"]]}]]]},{"id":"84ffffff721514785141d25f","class":"83ffffffdac33e2a035f07f3","children":[["83ffffffdac33e2a035f0129",[{"id":"84ffffff721514785141d27d","class":"83ffffffdac33e2a035f09f5","properties":[["83ffffffdac33e2a035f0b9f","123"]]}]],["83ffffffdac33e2a035f028e",[{"id":"83ffffffb3802c0151db830f","class":"83ffffffdac33e2a035f07f3","children":[["83ffffffdac33e2a035f0129",[{"id":"84ffffff721514785141d1e6","class":"84ffffff9a22d56250a12ae3","references":[["84ffffff9a22d56250a12d69","84ffffffe801a7387cb63efc"]]}]],["83ffffffdac33e2a035f028e",[{"id":"84ffffff721514785141d224","class":"84ffffff9a22d56250a12ae3","references":[["84ffffff9a22d56250a12d69","84ffffff721514785141d162"]]}]]]}]]]},{"id":"83ffffffb3802c0151db8368","class":"83ffffffdac33e2a035f07f3","children":[["83ffffffdac33e2a035f0129",[{"id":"83ffffffb3802c0151db8378","class":"83ffffffdac33e2a035f09f5","properties":[["83ffffffdac33e2a035f0b9f","123"]]}]],["83ffffffdac33e2a035f028e",[{"id":"83ffffffb3802c0151db838e","class":"83ffffffc5a5c4772047375d","children":[["83ffffffc5a5c47720473a16",[{"id":"83ffffffb3802c0151db83a2","class":"83ffffffdac33e2a035f09f5","properties":[["83ffffffdac33e2a035f0b9f","789"]]}]]]}]]]}]]]}]}
2 changes: 1 addition & 1 deletion model/test-language.ast-model

Large diffs are not rendered by default.

16 changes: 9 additions & 7 deletions src/ast/base_language.nim
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,11 @@ proc validateChildType(ctx: ModelComputationContextBase, node: AstNode, role: Ro
let expressionClass* = newNodeClass(IdExpression, "Expression", isAbstract=true)
# let typeClass* = newNodeClass(IdType, "Type", base=expressionClass)

let namedInterface* = newNodeClass(IdINamed, "INamed", isAbstract=true, isInterface=true,
properties=[PropertyDescription(id: IdINamedName, role: "name", typ: PropertyType.String)])

let declarationInterface* = newNodeClass(IdIDeclaration, "IDeclaration", isAbstract=true, isInterface=true, base=namedInterface)

let metaTypeClass* = newNodeClass(IdType, "Type", alias="type", base=expressionClass)
let stringTypeClass* = newNodeClass(IdString, "StringType", alias="string", base=expressionClass)
let int32TypeClass* = newNodeClass(IdInt32, "Int32Type", alias="i32", base=expressionClass)
Expand All @@ -99,11 +104,6 @@ let pointerTypeDeclClass* = newNodeClass(IdPointerTypeDecl, "PointerTypeDecl", a
children=[
NodeChildDescription(id: IdPointerTypeDeclTarget, role: "target", class: expressionClass.id, count: ChildCount.One)])

let namedInterface* = newNodeClass(IdINamed, "INamed", isAbstract=true, isInterface=true,
properties=[PropertyDescription(id: IdINamedName, role: "name", typ: PropertyType.String)])

let declarationInterface* = newNodeClass(IdIDeclaration, "IDeclaration", isAbstract=true, isInterface=true, base=namedInterface)

let castClass* = newNodeClass(IdCast, "Cast", alias="cast", base=expressionClass, children=[
NodeChildDescription(id: IdCastType, role: "type", class: expressionClass.id, count: ChildCount.One),
NodeChildDescription(id: IdCastValue, role: "value", class: expressionClass.id, count: ChildCount.One),
Expand Down Expand Up @@ -1997,10 +1997,11 @@ scopeComputers[IdThenCase] = proc(ctx: ModelComputationContextBase, node: AstNod
# debugf"compute scope for then case {node}"
return ctx.computeDefaultScope(node)

let baseInterfaces* = newLanguage(IdBaseInterfaces, "BaseInterfaces", @[namedInterface, declarationInterface])
registerBuilder(IdBaseInterfaces, newCellBuilder())

let baseLanguage* = newLanguage(IdBaseLanguage, "Base",
@[
namedInterface, declarationInterface,

# typeClass,
metaTypeClass, stringTypeClass, charTypeClass, voidTypeClass, functionTypeClass, structTypeClass, pointerTypeClass, pointerTypeDeclClass,
int32TypeClass, uint32TypeClass, int64TypeClass, uint64TypeClass, float32TypeClass, float64TypeClass,
Expand All @@ -2018,6 +2019,7 @@ let baseLanguage* = newLanguage(IdBaseLanguage, "Base",
structDefinitionClass, structMemberDefinitionClass, structParameterClass, structMemberAccessClass,
addressOfClass, derefClass, arrayAccessClass,
], typeComputers, valueComputers, scopeComputers, validationComputers,
baseLanguages=[baseInterfaces],
rootNodes=[
int32TypeInstance, uint32TypeInstance, int64TypeInstance, uint64TypeInstance, float32TypeInstance, float64TypeInstance, stringTypeInstance, voidTypeInstance, charTypeInstance, metaTypeInstance
])
Expand Down
2 changes: 2 additions & 0 deletions src/ast/lang/cell_language.nim
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ builder.defineCellDefinitionCommands IdReferenceCellDefinition, idNone(), [
CellBuilderCommand(kind: ConstantCell, text: "ref", themeForegroundColors: @["keyword"], disableEditing: true),
CellBuilderCommand(kind: Children, childrenRole: IdReferenceCellDefinitionRole, themeForegroundColors: @["variable"]),
CellBuilderCommand(kind: ConstantCell, text: "|", themeForegroundColors: @["punctuation"], disableEditing: true, flags: &{NoSpaceLeft, NoSpaceRight}),
CellBuilderCommand(kind: Children, childrenRole: IdReferenceCellDefinitionTargetProperty, placeholder: "<target property>".some, themeForegroundColors: @["variable"]),
CellBuilderCommand(kind: ConstantCell, text: "|", themeForegroundColors: @["punctuation"], disableEditing: true, flags: &{NoSpaceLeft, NoSpaceRight}),
CellBuilderCommand(kind: Children, childrenRole: IdCellDefinitionCellFlags, separator: ",".some, placeholder: "flags".some, uiFlags: &{LayoutHorizontal}),
CellBuilderCommand(kind: ConstantCell, text: "|", themeForegroundColors: @["punctuation"], disableEditing: true, flags: &{NoSpaceLeft, NoSpaceRight}),
CellBuilderCommand(kind: Children, childrenRole: IdCellDefinitionForegroundColor, separator: ",".some, placeholder: "fg".some, uiFlags: &{LayoutHorizontal}),
Expand Down
115 changes: 91 additions & 24 deletions src/ast/lang/lang_language.nim
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@ let classDefinitionClass* = newNodeClass(IdClassDefinition, "ClassDefinition", a
NodeChildDescription(id: IdClassDefinitionReferences, role: "references", class: IdReferenceDefinition, count: ChildCount.ZeroOrMore),
NodeChildDescription(id: IdClassDefinitionChildren, role: "children", class: IdChildrenDefinition, count: ChildCount.ZeroOrMore),
NodeChildDescription(id: IdClassDefinitionSubstitutionProperty, role: "substitution property", class: IdRoleReference, count: ChildCount.ZeroOrOne),
])
NodeChildDescription(id: IdClassDefinitionSubstitutionReference, role: "substitution reference", class: IdRoleReference, count: ChildCount.ZeroOrOne),
])

var builder = newCellBuilder()

Expand Down Expand Up @@ -254,6 +255,14 @@ builder.addBuilderFor IdClassDefinition, idNone(), proc(map: NodeCellMap, builde
placeholder: "<role>"
sub

vertCell.add block:
var sub = CollectionCell(id: newId().CellId, node: owner ?? node, referenceNode: node, uiFlags: &{LayoutHorizontal})
sub.add ConstantCell(node: owner ?? node, referenceNode: node, text: "substitution reference:", themeForegroundColors: @["punctuation", "&editor.foreground"], disableEditing: true)
sub.add block:
buildChildrenT(builder, map, node, owner, IdClassDefinitionSubstitutionReference, &{LayoutVertical}, &{OnNewLine, IndentChildren}):
placeholder: "<role>"
sub

cell.add vertCell
cell.add ConstantCell(node: owner ?? node, referenceNode: node, text: "}", themeForegroundColors: @["punctuation", "&editor.foreground"], disableEditing: true, flags: &{OnNewLine})

Expand Down Expand Up @@ -299,6 +308,9 @@ scopeComputers[IdClassReference] = proc(ctx: ModelComputationContextBase, node:
if aspect.class == IdClassDefinition:
nodes.add aspect

# todo: I want to be able to reference RoleReference in cell-builder.ast-model, which is only in the language model so far.
# Maybe move role reference to a separate model?
# With this I can also referene stuff from the lang language model in e.g. the test language, which shouldn't be possible
for language in node.model.languages:
for root in language.model.rootNodes:
for _, aspect in root.children(IdLangRootChildren):
Expand All @@ -316,13 +328,15 @@ scopeComputers[IdClassDefinition] = proc(ctx: ModelComputationContextBase, node:
debugf"compute scope for class definition {node}"
var nodes: seq[AstNode] = @[]

# todo: improve this
for model in node.model.models:
for root in model.rootNodes:
for _, aspect in root.children(IdLangRootChildren):
if aspect.class == IdClassDefinition:
nodes.add aspect

# todo: I want to be able to reference RoleReference in cell-builder.ast-model, which is only in the language model so far.
# Maybe move role reference to a separate model?
# With this I can also referene stuff from the lang language model in e.g. the test language, which shouldn't be possible
for language in node.model.languages:
for root in language.model.rootNodes:
for _, aspect in root.children(IdLangRootChildren):
Expand All @@ -345,10 +359,51 @@ scopeComputers[IdClassDefinition] = proc(ctx: ModelComputationContextBase, node:

return nodes

proc collectRoles(classNode: AstNode, nodes: var seq[AstNode]) =
# echo fmt"collectRoles: {classNode.dump(recurse=true)}"
for _, prop in classNode.children(IdClassDefinitionProperties):
# echo fmt"{classNode}: {prop}"
nodes.add prop

for _, reference in classNode.children(IdClassDefinitionReferences):
nodes.add reference

for _, children in classNode.children(IdClassDefinitionChildren):
nodes.add children

if classNode.firstChild(IdClassDefinitionBaseClass).getSome(baseClassReference):
if baseClassReference.resolveReference(IdClassReferenceTarget).getSome(baseClassNode):
collectRoles(baseClassNode, nodes)

for _, interfaceReference in classNode.children(IdClassDefinitionInterfaces):
if interfaceReference.resolveReference(IdClassReferenceTarget).getSome(baseClassNode):
collectRoles(baseClassNode, nodes)

scopeComputers[IdRoleReference] = proc(ctx: ModelComputationContextBase, node: AstNode): seq[AstNode] =
debugf"compute scope for role reference {node}"
var nodes: seq[AstNode] = @[]

if node.role == IdReferenceCellDefinitionTargetProperty:
let referenceCellNode = node.parent
let referenceRoleNode = referenceCellNode.firstChild(IdReferenceCellDefinitionRole).getOr:
return @[]

let referenceRole = referenceRoleNode.resolveReference(IdRoleReferenceTarget).getOr:
return @[]

# debugf"referenceRole: {referenceRole}"

let classReferenceNode = referenceRole.firstChild(IdReferenceDefinitionClass).getOr:
return @[]

# debugf"classReferenceNode: {classReferenceNode}"
let classNode = classReferenceNode.resolveReference(IdClassReferenceTarget).getOr:
return @[]

# debugf"classNode: {classNode.dump(recurse=true)}"
collectRoles(classNode, nodes)
return nodes

# todo: improve this
var parent = node.parent
var classNode: AstNode = nil
Expand All @@ -368,14 +423,7 @@ scopeComputers[IdRoleReference] = proc(ctx: ModelComputationContextBase, node: A
if classNode.isNil:
return nodes

for _, prop in classNode.children(IdClassDefinitionProperties):
nodes.add prop

for _, reference in classNode.children(IdClassDefinitionReferences):
nodes.add reference

for _, children in classNode.children(IdClassDefinitionChildren):
nodes.add children
collectRoles(classNode, nodes)

return nodes

Expand Down Expand Up @@ -403,10 +451,15 @@ proc createNodeClassFromLangDefinition*(classMap: var Table[ClassId, NodeClass],
else:
RoleId.none

let substitutionReference = if def.firstChild(IdClassDefinitionSubstitutionReference).getSome(substitutionReference):
substitutionReference.reference(IdRoleReferenceTarget).RoleId.some
else:
RoleId.none

# use node id of the class definition node as class id
var class = newNodeClass(def.id.ClassId, name, alias=alias,
isAbstract=isAbstract, isInterface=isInterface, isFinal=isFinal, canBeRoot=canBeRoot,
substitutionProperty=substitutionProperty, precedence=precedence)
substitutionProperty=substitutionProperty, substitutionReference=substitutionReference, precedence=precedence)
classMap[def.id.ClassId] = class

for _, prop in def.children(IdClassDefinitionProperties):
Expand Down Expand Up @@ -559,26 +612,29 @@ proc createCellBuilderCommandFromDefinition(builder: CellBuilder, def: AstNode,
themeForegroundColors: foregroundColors, themeBackgroundColors: backgroundColors)

elif def.class == IdReferenceCellDefinition:
let targetProperty = def.firstChild(IdReferenceCellDefinitionTargetProperty).mapIt(it.reference(IdRoleReferenceTarget).RoleId)

if def.firstChild(IdReferenceCellDefinitionRole).getSome(referenceRoleNode):
let referenceRole = referenceRoleNode.reference(IdRoleReferenceTarget).RoleId
commands.add CellBuilderCommand(kind: ReferenceCell, referenceRole: referenceRole, uiFlags: uiFlags, flags: cellFlags, shadowText: shadowText, disableEditing: disableEditing, disableSelection: disableSelection, deleteNeighbor: deleteNeighbor,
themeForegroundColors: foregroundColors, themeBackgroundColors: backgroundColors)
commands.add CellBuilderCommand(kind: ReferenceCell, referenceRole: referenceRole, targetProperty: targetProperty, uiFlags: uiFlags, flags: cellFlags, shadowText: shadowText,
disableEditing: disableEditing, disableSelection: disableSelection, deleteNeighbor: deleteNeighbor,
themeForegroundColors: foregroundColors, themeBackgroundColors: backgroundColors)
else:
log lvlError, fmt"Missing role for property definition: {def}"

elif def.class == IdPropertyCellDefinition:
if def.firstChild(IdPropertyCellDefinitionRole).getSome(propertyRoleNode):
let propertyRole = propertyRoleNode.reference(IdRoleReferenceTarget).RoleId
commands.add CellBuilderCommand(kind: PropertyCell, propertyRole: propertyRole, uiFlags: uiFlags, flags: cellFlags, shadowText: shadowText, disableEditing: disableEditing, disableSelection: disableSelection, deleteNeighbor: deleteNeighbor,
themeForegroundColors: foregroundColors, themeBackgroundColors: backgroundColors)
themeForegroundColors: foregroundColors, themeBackgroundColors: backgroundColors)
else:
log lvlError, fmt"Missing role for property definition: {def}"

elif def.class == IdChildrenCellDefinition:
if def.firstChild(IdChildrenCellDefinitionRole).getSome(childRoleNode):
let childRole = childRoleNode.reference(IdRoleReferenceTarget).RoleId
commands.add CellBuilderCommand(kind: Children, childrenRole: childRole, uiFlags: uiFlags, flags: cellFlags, shadowText: shadowText, disableEditing: disableEditing, disableSelection: disableSelection, deleteNeighbor: deleteNeighbor,
themeForegroundColors: foregroundColors, themeBackgroundColors: backgroundColors)
themeForegroundColors: foregroundColors, themeBackgroundColors: backgroundColors)
else:
log lvlError, fmt"Missing role for children definition: {def}"

Expand Down Expand Up @@ -647,6 +703,11 @@ proc createNodeFromNodeClass(classes: var Table[ClassId, AstNode], class: NodeCl
roleReference.setReference(IdRoleReferenceTarget, property.NodeId)
result.add(IdClassDefinitionSubstitutionProperty, roleReference)

if class.substitutionReference.getSome(property):
var roleReference = newAstNode(roleReferenceClass)
roleReference.setReference(IdRoleReferenceTarget, property.NodeId)
result.add(IdClassDefinitionSubstitutionReference, roleReference)

for property in class.properties:
var propertyNode = newAstNode(propertyDefinitionClass, property.id.NodeId.some)
propertyNode.setProperty(IdINamedName, PropertyValue(kind: String, stringValue: property.role))
Expand Down Expand Up @@ -700,13 +761,6 @@ proc createNodeFromNodeClass(classes: var Table[ClassId, AstNode], class: NodeCl

# debugf"node {result.dump(recurse=true)}"

proc createNodesForLanguage*(language: Language): AstNode =
result = newAstNode(langRootClass)

var classes = initTable[ClassId, AstNode]()
for class in language.classes.values:
result.add IdLangRootChildren, createNodeFromNodeClass(classes, class)

let langLanguage* = newLanguage(IdLangLanguage, "Language Creation", @[
langRootClass, langAspectClass,
roleDescriptorInterface,
Expand All @@ -716,10 +770,23 @@ let langLanguage* = newLanguage(IdLangLanguage, "Language Creation", @[
], typeComputers, valueComputers, scopeComputers, validationComputers)
registerBuilder(IdLangLanguage, builder)

proc createModelForLanguage*(language: Language): Model =
result = newModel(language.id.ModelId)
result.addLanguage(langLanguage)

let root = newAstNode(langRootClass)
var classes = initTable[ClassId, AstNode]()
for class in language.classes.values:
root.add IdLangRootChildren, createNodeFromNodeClass(classes, class)

result.addRootNode(root)

# let langLanguageModel = block:
# let model = newModel(IdLangLanguageModel)
# model.addLanguage(langLanguage)
# model.addRootNode createNodesForLanguage(langLanguage)
# model.addRootNode createModelForLanguage(langLanguage)
# model
# langLanguage.model = langLanguageModel
langLanguage.model.addRootNode createNodesForLanguage(langLanguage)
langLanguage.model.addRootNode createModelForLanguage(langLanguage).rootNodes[0]

let baseInterfacesModel* = createModelForLanguage(base_language.baseInterfaces)
Loading

0 comments on commit 4d0f699

Please sign in to comment.