Skip to content

Commit

Permalink
more progress
Browse files Browse the repository at this point in the history
  • Loading branch information
Nimaoth committed Nov 30, 2023
1 parent 8654987 commit d5fdff3
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 23 deletions.
64 changes: 49 additions & 15 deletions src/ast/lang/lang_language.nim
Original file line number Diff line number Diff line change
Expand Up @@ -344,8 +344,12 @@ let langLanguage* = newLanguage(IdLangLanguage, @[
countClass, countZeroOrOneClass, countOneClass, countZeroOrMoreClass, countOneOrMoreClass,
], builder, typeComputers, valueComputers, scopeComputers)

proc createNodeClassFromLangDefinition*(def: AstNode): Option[NodeClass] =
log lvlInfo, fmt"createNodeClassFromLangDefinition {def.dump(recurse=true)}"
proc createNodeClassFromLangDefinition*(classMap: var Table[ClassId, NodeClass], def: AstNode): Option[NodeClass] =
if classMap.contains(def.id.ClassId):
return classMap[def.id.ClassId].some

# log lvlInfo, fmt"createNodeClassFromLangDefinition {def.dump(recurse=true)}"

let name = def.property(IdINamedName).get.stringValue
let alias = def.property(IdClassDefinitionAlias).get.stringValue

Expand All @@ -364,6 +368,12 @@ proc createNodeClassFromLangDefinition*(def: AstNode): Option[NodeClass] =
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)
classMap[def.id.ClassId] = class

for _, prop in def.children(IdClassDefinitionProperties):
let propName = prop.property(IdINamedName).get.stringValue
let typ = if prop.firstChild(IdPropertyDefinitionType).getSome(typ):
Expand All @@ -380,11 +390,11 @@ proc createNodeClassFromLangDefinition*(def: AstNode): Option[NodeClass] =
log lvlError, fmt"No property type specified for {prop}"
return NodeClass.none

properties.add PropertyDescription(id: prop.id.RoleId, role: propName, typ: typ)
class.properties.add PropertyDescription(id: prop.id.RoleId, role: propName, typ: typ)

for _, reference in def.children(IdClassDefinitionReferences):
let referenceName = reference.property(IdINamedName).get.stringValue
let class: ClassId = if reference.firstChild(IdReferenceDefinitionClass).getSome(classNode):
let classId: ClassId = if reference.firstChild(IdReferenceDefinitionClass).getSome(classNode):
assert classNode.class == IdClassReference
if classNode.resolveReference(IdClassReferenceTarget).getSome(target):
# use node id of the class definition node as class id
Expand All @@ -396,11 +406,11 @@ proc createNodeClassFromLangDefinition*(def: AstNode): Option[NodeClass] =
log lvlError, fmt"No class specified for {reference}"
return NodeClass.none

references.add NodeReferenceDescription(id: reference.id.RoleId, role: referenceName, class: class)
class.references.add NodeReferenceDescription(id: reference.id.RoleId, role: referenceName, class: classId)

for _, children in def.children(IdClassDefinitionChildren):
let childrenName = children.property(IdINamedName).get.stringValue
let class: ClassId = if children.firstChild(IdChildrenDefinitionClass).getSome(classNode):
let classId: ClassId = if children.firstChild(IdChildrenDefinitionClass).getSome(classNode):
assert classNode.class == IdClassReference
if classNode.resolveReference(IdClassReferenceTarget).getSome(target):
# use node id of the class definition node as class id
Expand Down Expand Up @@ -428,21 +438,45 @@ proc createNodeClassFromLangDefinition*(def: AstNode): Option[NodeClass] =
log lvlError, fmt"No child count specified for {children}"
return NodeClass.none

childDescriptions.add NodeChildDescription(id: children.id.RoleId, role: childrenName, class: class, count: count)
class.children.add NodeChildDescription(id: children.id.RoleId, role: childrenName, class: classId, count: count)

let baseClass: NodeClass = nil # todo
let interfaces: seq[NodeClass] = @[] # todo
if def.firstChild(IdClassDefinitionBaseClass).getSome(baseClassReference):
if baseClassReference.resolveReference(IdClassReferenceTarget).getSome(baseClassNode):
if createNodeClassFromLangDefinition(classMap, baseClassNode).getSome(baseClass):
class.base = baseClass
else:
log lvlError, fmt"Failed to create base class for {def}: {baseClassNode}"
return NodeClass.none

for _, interfaceReferenceNode in def.children(IdClassDefinitionInterfaces):
if interfaceReferenceNode.resolveReference(IdClassReferenceTarget).getSome(interfaceNode):
if createNodeClassFromLangDefinition(classMap, interfaceNode).getSome(interfaceClass):
class.interfaces.add interfaceClass
else:
log lvlError, fmt"Failed to create base class for {def}: {interfaceNode}"
return NodeClass.none

# use node id of the class definition node as class id
let class = newNodeClass(def.id.ClassId, name, alias=alias, base=baseClass, interfaces=interfaces,
isAbstract=isAbstract, isInterface=isInterface, isFinal=isFinal, canBeRoot=canBeRoot,
substitutionProperty=substitutionProperty, precedence=precedence,
properties=properties, references=references, children=childDescriptions)
# debugf"{class}"
print class
# print class

return class.some

proc createLanguageFromNodes*(def: AstNode): Language =
log lvlInfo, fmt"createLanguageFromNodes"
var classMap = initTable[ClassId, NodeClass]()
var classes: seq[NodeClass] = @[]
for _, c in def.children(IdLangRootChildren):
if c.class == IdClassDefinition:
if createNodeClassFromLangDefinition(classMap, c).getSome(class):
classes.add class

var builder = newCellBuilder()
var typeComputers = initTable[ClassId, proc(ctx: ModelComputationContextBase, node: AstNode): AstNode]()
var valueComputers = initTable[ClassId, proc(ctx: ModelComputationContextBase, node: AstNode): AstNode]()
var scopeComputers = initTable[ClassId, proc(ctx: ModelComputationContextBase, node: AstNode): seq[AstNode]]()

result = newLanguage(def.id.LanguageId, classes, builder, typeComputers, valueComputers, scopeComputers)

proc createNodeFromNodeClass(classes: var Table[ClassId, AstNode], class: NodeClass): AstNode =
# log lvlInfo, fmt"createNodeFromNodeClass {class.name}"

Expand Down
8 changes: 4 additions & 4 deletions src/ast/model.nim
Original file line number Diff line number Diff line change
Expand Up @@ -76,14 +76,14 @@ type
id {.getter.}: ClassId
name {.getter.}: string
alias {.getter.}: string
base {.getter.}: NodeClass
base*: NodeClass
interfaces {.getter.}: seq[NodeClass]
isAbstract {.getter.}: bool
isFinal {.getter.}: bool
isInterface {.getter.}: bool
properties {.getter.}: seq[PropertyDescription]
children {.getter.}: seq[NodeChildDescription]
references {.getter.}: seq[NodeReferenceDescription]
properties*: seq[PropertyDescription]
children*: seq[NodeChildDescription]
references*: seq[NodeReferenceDescription]
substitutionProperty {.getter.}: Option[RoleId]
precedence {.getter.}: int
canBeRoot {.getter.}: bool
Expand Down
6 changes: 2 additions & 4 deletions src/model_document.nim
Original file line number Diff line number Diff line change
Expand Up @@ -3016,10 +3016,8 @@ proc compileLanguage*(self: ModelDocumentEditor) {.expose("editor.model").} =
return

for root in self.document.model.rootNodes:
for _, child in root.children(IdLangRootChildren):
if child.class == IdClassDefinition:
let class = createNodeClassFromLangDefinition(child)
# todo
let language = createLanguageFromNodes(root)
# todo

proc addRootNode*(self: ModelDocumentEditor) {.expose("editor.model").} =
var popup = self.app.createSelectorPopup().SelectorPopup
Expand Down

0 comments on commit d5fdff3

Please sign in to comment.