Skip to content

Commit

Permalink
more progress on lang lang
Browse files Browse the repository at this point in the history
  • Loading branch information
Nimaoth committed Nov 30, 2023
1 parent 2d7ff14 commit 5d48acc
Show file tree
Hide file tree
Showing 8 changed files with 529 additions and 155 deletions.
409 changes: 274 additions & 135 deletions model/test-language.ast-model

Large diffs are not rendered by default.

9 changes: 9 additions & 0 deletions scripting/absytree_internal.nim
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,12 @@ proc editor_model_getContextWithMode_string_ModelDocumentEditor_string_impl*(
proc editor_model_isThickCursor_bool_ModelDocumentEditor_impl*(
self: ModelDocumentEditor): bool =
discard
proc editor_model_gotoDefinition_void_ModelDocumentEditor_bool_impl*(
self: ModelDocumentEditor; select: bool = false) =
discard
proc editor_model_toggleBoolCell_void_ModelDocumentEditor_bool_impl*(
self: ModelDocumentEditor; select: bool = false) =
discard
proc editor_model_moveCursorLeft_void_ModelDocumentEditor_bool_impl*(
self: ModelDocumentEditor; select: bool = false) =
discard
Expand Down Expand Up @@ -393,6 +399,9 @@ proc editor_model_addRootNode_void_ModelDocumentEditor_impl*(
proc editor_model_saveProject_void_ModelDocumentEditor_impl*(
self: ModelDocumentEditor) =
discard
proc editor_model_loadBaseLanguageModel_void_ModelDocumentEditor_impl*(
self: ModelDocumentEditor) =
discard
proc editor_getBackend_Backend_App_impl*(): Backend =
discard
proc editor_toggleShowDrawnNodes_void_App_impl*() =
Expand Down
6 changes: 6 additions & 0 deletions scripting/absytree_internal_wasm.nim
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,10 @@ proc editor_model_getContextWithMode_string_ModelDocumentEditor_string_impl(
self: ModelDocumentEditor; context: string): string {.importc.}
proc editor_model_isThickCursor_bool_ModelDocumentEditor_impl(
self: ModelDocumentEditor): bool {.importc.}
proc editor_model_gotoDefinition_void_ModelDocumentEditor_bool_impl(
self: ModelDocumentEditor; select: bool = false) {.importc.}
proc editor_model_toggleBoolCell_void_ModelDocumentEditor_bool_impl(
self: ModelDocumentEditor; select: bool = false) {.importc.}
proc editor_model_moveCursorLeft_void_ModelDocumentEditor_bool_impl(
self: ModelDocumentEditor; select: bool = false) {.importc.}
proc editor_model_moveCursorRight_void_ModelDocumentEditor_bool_impl(
Expand Down Expand Up @@ -263,6 +267,8 @@ proc editor_model_addRootNode_void_ModelDocumentEditor_impl(
self: ModelDocumentEditor) {.importc.}
proc editor_model_saveProject_void_ModelDocumentEditor_impl(
self: ModelDocumentEditor) {.importc.}
proc editor_model_loadBaseLanguageModel_void_ModelDocumentEditor_impl(
self: ModelDocumentEditor) {.importc.}
proc editor_getBackend_Backend_App_impl(): Backend {.importc.}
proc editor_toggleShowDrawnNodes_void_App_impl() {.importc.}
proc editor_saveAppState_void_App_impl() {.importc.}
Expand Down
6 changes: 6 additions & 0 deletions scripting/editor_model_api.nim
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ proc getContextWithMode*(self: ModelDocumentEditor; context: string): string =
context)
proc isThickCursor*(self: ModelDocumentEditor): bool =
editor_model_isThickCursor_bool_ModelDocumentEditor_impl(self)
proc gotoDefinition*(self: ModelDocumentEditor; select: bool = false) =
editor_model_gotoDefinition_void_ModelDocumentEditor_bool_impl(self, select)
proc toggleBoolCell*(self: ModelDocumentEditor; select: bool = false) =
editor_model_toggleBoolCell_void_ModelDocumentEditor_bool_impl(self, select)
proc moveCursorLeft*(self: ModelDocumentEditor; select: bool = false) =
editor_model_moveCursorLeft_void_ModelDocumentEditor_bool_impl(self, select)
proc moveCursorRight*(self: ModelDocumentEditor; select: bool = false) =
Expand Down Expand Up @@ -109,3 +113,5 @@ proc addRootNode*(self: ModelDocumentEditor) =
editor_model_addRootNode_void_ModelDocumentEditor_impl(self)
proc saveProject*(self: ModelDocumentEditor) =
editor_model_saveProject_void_ModelDocumentEditor_impl(self)
proc loadBaseLanguageModel*(self: ModelDocumentEditor) =
editor_model_loadBaseLanguageModel_void_ModelDocumentEditor_impl(self)
52 changes: 52 additions & 0 deletions scripting/editor_model_api_wasm.nim
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,44 @@ proc isThickCursor*(self: ModelDocumentEditor): bool =
result = parseJson($res).jsonTo(typeof(result))


proc editor_model_gotoDefinition_void_ModelDocumentEditor_bool_wasm(arg: cstring): cstring {.
importc.}
proc gotoDefinition*(self: ModelDocumentEditor; select: bool = false) =
var argsJson = newJArray()
argsJson.add block:
when ModelDocumentEditor is JsonNode:
self
else:
self.toJson()
argsJson.add block:
when bool is JsonNode:
select
else:
select.toJson()
let argsJsonString = $argsJson
let res {.used.} = editor_model_gotoDefinition_void_ModelDocumentEditor_bool_wasm(
argsJsonString.cstring)


proc editor_model_toggleBoolCell_void_ModelDocumentEditor_bool_wasm(arg: cstring): cstring {.
importc.}
proc toggleBoolCell*(self: ModelDocumentEditor; select: bool = false) =
var argsJson = newJArray()
argsJson.add block:
when ModelDocumentEditor is JsonNode:
self
else:
self.toJson()
argsJson.add block:
when bool is JsonNode:
select
else:
select.toJson()
let argsJsonString = $argsJson
let res {.used.} = editor_model_toggleBoolCell_void_ModelDocumentEditor_bool_wasm(
argsJsonString.cstring)


proc editor_model_moveCursorLeft_void_ModelDocumentEditor_bool_wasm(arg: cstring): cstring {.
importc.}
proc moveCursorLeft*(self: ModelDocumentEditor; select: bool = false) =
Expand Down Expand Up @@ -723,3 +761,17 @@ proc saveProject*(self: ModelDocumentEditor) =
let res {.used.} = editor_model_saveProject_void_ModelDocumentEditor_wasm(
argsJsonString.cstring)


proc editor_model_loadBaseLanguageModel_void_ModelDocumentEditor_wasm(
arg: cstring): cstring {.importc.}
proc loadBaseLanguageModel*(self: ModelDocumentEditor) =
var argsJson = newJArray()
argsJson.add block:
when ModelDocumentEditor is JsonNode:
self
else:
self.toJson()
let argsJsonString = $argsJson
let res {.used.} = editor_model_loadBaseLanguageModel_void_ModelDocumentEditor_wasm(
argsJsonString.cstring)

151 changes: 138 additions & 13 deletions src/ast/lang/lang_language.nim
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,14 @@ let childrenDefinitionClass* = newNodeClass(IdChildrenDefinition, "ChildrenDefin
NodeChildDescription(id: IdChildrenDefinitionCount, role: "count", class: IdCount, count: ChildCount.One),
])

let classDefinitionClass* = newNodeClass(IdClassDefinition, "ClassDefinition", alias="class", interfaces=[namedInterface], canBeRoot=true,
let langAspectClass* = newNodeClass(IdLangAspect, "LangAspect", isAbstract=true)

let langRootClass* = newNodeClass(IdLangRoot, "LangRoot", canBeRoot=true,
children=[NodeChildDescription(id: IdLangRootChildren, role: "children", class: IdLangAspect, count: ChildCount.ZeroOrMore)])

let classDefinitionClass* = newNodeClass(IdClassDefinition, "ClassDefinition", alias="class", base=langAspectClass, interfaces=[namedInterface],
properties=[
PropertyDescription(id: IdClassDefinitionAlias, role: "alias", typ: PropertyType.String),
PropertyDescription(id: IdClassDefinitionAbstract, role: "abstract", typ: PropertyType.Bool),
PropertyDescription(id: IdClassDefinitionInterface, role: "interface", typ: PropertyType.Bool),
PropertyDescription(id: IdClassDefinitionFinal, role: "final", typ: PropertyType.Bool),
Expand Down Expand Up @@ -128,6 +134,21 @@ builder.addBuilderFor IdChildrenDefinition, idNone(), proc(builder: CellBuilder,

return cell

builder.addBuilderFor IdLangRoot, idNone(), proc(builder: CellBuilder, node: AstNode): Cell =
var cell = CollectionCell(id: newId().CellId, node: node, uiFlags: &{LayoutVertical})
cell.fillChildren = proc(map: NodeCellMap) =
cell.add block:
buildChildrenT(builder, map, node, IdLangRootChildren, &{LayoutVertical}, 0.CellFlags):
separator: ConstantCell(node: node, text: "", disableEditing: true, disableSelection: true)
placeholder: "..."

return cell

builder.addBuilderFor IdLangAspect, idNone(), proc(builder: CellBuilder, node: AstNode): Cell =
# return PlaceholderCell(id: newId().CellId, node: node, role: IdClassReferenceTarget, shadowText: "<class>")
var cell = ConstantCell(id: newId().CellId, node: node, shadowText: "...", themeBackgroundColors: @["&inputValidation.errorBackground", "&debugConsole.errorForeground"])
return cell

builder.addBuilderFor IdClassDefinition, idNone(), proc(builder: CellBuilder, node: AstNode): Cell =
var cell = CollectionCell(id: newId().CellId, node: node, uiFlags: &{LayoutHorizontal})
cell.fillChildren = proc(map: NodeCellMap) =
Expand All @@ -150,6 +171,10 @@ builder.addBuilderFor IdClassDefinition, idNone(), proc(builder: CellBuilder, no

var vertCell = CollectionCell(id: newId().CellId, node: node, uiFlags: &{LayoutVertical}, flags: &{OnNewLine, IndentChildren})

vertCell.addHorizontal(node, 0.CellFlags):
sub.add ConstantCell(node: node, text: "alias", themeForegroundColors: @["keyword"], disableEditing: true)
sub.add PropertyCell(id: newId().CellId, node: node, property: IdClassDefinitionAlias, themeForegroundColors: @["variable"])

vertCell.addHorizontal(node, 0.CellFlags):
sub.add ConstantCell(node: node, text: "abstract", themeForegroundColors: @["keyword"], disableEditing: true)
sub.add PropertyCell(id: newId().CellId, node: node, property: IdClassDefinitionAbstract, themeForegroundColors: @["variable"])
Expand Down Expand Up @@ -246,13 +271,15 @@ scopeComputers[IdClassReference] = proc(ctx: ModelComputationContextBase, node:
echo "model ", model.id
for root in model.rootNodes:
echo "import root ", root
if root.class == IdClassDefinition:
nodes.add root
for _, aspect in root.children(IdLangRootChildren):
if aspect.class == IdClassDefinition:
nodes.add aspect

for root in node.model.rootNodes:
echo "root ", root
if root.class == IdClassDefinition:
nodes.add root
for _, aspect in root.children(IdLangRootChildren):
if aspect.class == IdClassDefinition:
nodes.add aspect

return nodes

Expand All @@ -263,12 +290,14 @@ scopeComputers[IdClassDefinition] = proc(ctx: ModelComputationContextBase, node:
# todo: improve this
for model in node.model.models:
for root in model.rootNodes:
if root.class == IdClassDefinition:
nodes.add root
for _, aspect in root.children(IdLangRootChildren):
if aspect.class == IdClassDefinition:
nodes.add aspect

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

for _, prop in node.children(IdClassDefinitionProperties):
nodes.add prop
Expand Down Expand Up @@ -305,6 +334,7 @@ scopeComputers[IdRoleReference] = proc(ctx: ModelComputationContextBase, node: A
return nodes

let langLanguage* = newLanguage(IdLangLanguage, @[
langRootClass, langAspectClass,
roleDescriptorInterface,
propertyTypeClass, propertyTypeBoolClass, propertyTypeStringClass, propertyTypeNumberClass, propertyDefinitionClass, classDefinitionClass,
classReferenceClass, roleReferenceClass, referenceDefinitionClass, childrenDefinitionClass,
Expand All @@ -314,13 +344,23 @@ let langLanguage* = newLanguage(IdLangLanguage, @[
proc createNodeClassFromLangDefinition*(def: AstNode): Option[NodeClass] =
log lvlInfo, fmt"createNodeClassFromLangDefinition {def.dump(recurse=true)}"
let name = def.property(IdINamedName).get.stringValue
let alias = "todo"
let canBeRoot = true # todo
let alias = def.property(IdClassDefinitionAlias).get.stringValue

let isAbstract = def.property(IdClassDefinitionAbstract).get.boolValue
let isInterface = def.property(IdClassDefinitionInterface).get.boolValue
let isFinal = def.property(IdClassDefinitionFinal).get.boolValue
let canBeRoot = def.property(IdClassDefinitionCanBeRoot).get.boolValue
let precedence = def.property(IdClassDefinitionPrecedence).get.intValue

var properties = newSeqOfCap[PropertyDescription](def.childCount(IdClassDefinitionProperties))
var references = newSeqOfCap[NodeReferenceDescription](def.childCount(IdClassDefinitionReferences))
var childDescriptions = newSeqOfCap[NodeChildDescription](def.childCount(IdClassDefinitionChildren))

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

for _, prop in def.children(IdClassDefinitionProperties):
let propName = prop.property(IdINamedName).get.stringValue
let typ = if prop.firstChild(IdPropertyDefinitionType).getSome(typ):
Expand Down Expand Up @@ -387,9 +427,94 @@ proc createNodeClassFromLangDefinition*(def: AstNode): Option[NodeClass] =

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

let baseClass: NodeClass = nil

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

return class.some
return class.some

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

result = newAstNode(classDefinitionClass, class.id.NodeId.some)
# classes[class.id] = result

result.setProperty(IdINamedName, PropertyValue(kind: String, stringValue: class.name))
result.setProperty(IdClassDefinitionAlias, PropertyValue(kind: String, stringValue: class.alias))

result.setProperty(IdClassDefinitionAbstract, PropertyValue(kind: Bool, boolValue: class.isAbstract))
result.setProperty(IdClassDefinitionInterface, PropertyValue(kind: Bool, boolValue: class.isInterface))
result.setProperty(IdClassDefinitionFinal, PropertyValue(kind: Bool, boolValue: class.isFinal))
result.setProperty(IdClassDefinitionCanBeRoot, PropertyValue(kind: Bool, boolValue: class.canBeRoot))
result.setProperty(IdClassDefinitionPrecedence, PropertyValue(kind: Int, intValue: class.precedence))

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

for property in class.properties:
var propertyNode = newAstNode(propertyDefinitionClass, property.id.NodeId.some)
propertyNode.setProperty(IdINamedName, PropertyValue(kind: String, stringValue: property.role))

let propertyTypeClass = if property.typ == Int:
propertyTypeNumberClass
elif property.typ == String:
propertyTypeStringClass
elif property.typ == Bool:
propertyTypeBoolClass
else:
log lvlError, fmt"Invalid property type specified for {property}"
return nil

propertyNode.add(IdPropertyDefinitionType, newAstNode(propertyTypeClass))
result.add(IdClassDefinitionProperties, propertyNode)

for reference in class.references:
var referenceNode = newAstNode(referenceDefinitionClass, reference.id.NodeId.some)
referenceNode.setProperty(IdINamedName, PropertyValue(kind: String, stringValue: reference.role))

let classReference = newAstNode(classReferenceClass)
classReference.setReference(IdClassReferenceTarget, reference.class.NodeId)
referenceNode.add(IdReferenceDefinitionClass, classReference)

result.add(IdClassDefinitionReferences, referenceNode)

for children in class.children:
var childrenNode = newAstNode(childrenDefinitionClass, children.id.NodeId.some)
childrenNode.setProperty(IdINamedName, PropertyValue(kind: String, stringValue: children.role))

let classReference = newAstNode(classReferenceClass)
classReference.setReference(IdClassReferenceTarget, children.class.NodeId)
childrenNode.add(IdChildrenDefinitionClass, classReference)

let childrenCountClass = if children.count == ChildCount.ZeroOrOne:
countZeroOrOneClass
elif children.count == ChildCount.One:
countOneClass
elif children.count == ChildCount.ZeroOrMore:
countZeroOrMoreClass
elif children.count == ChildCount.OneOrMore:
countOneOrMoreClass
else:
log lvlError, fmt"Invalid child count specified for {children}"
return nil

childrenNode.add(IdChildrenDefinitionCount, newAstNode(childrenCountClass))

result.add(IdClassDefinitionChildren, childrenNode)

# 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)
9 changes: 5 additions & 4 deletions src/ast_ids.nim
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,11 @@ let IdGenericTypeValue* = "654fbb281446e19b3822521b".parseId.RoleId
# lang language
let IdLangLanguage* = "654fbb281446e19b3822523f".parseId.LanguageId

let IdLangRoot* = "654fbb281446e19b3822524f".parseId.ClassId
let IdLangRootChildren* = "654fbb281446e19b38225250".parseId.RoleId

let IdLangAspect* = "654fbb281446e19b38225251".parseId.ClassId

let IdClassDefinition* = "654fbb281446e19b3822522a".parseId.ClassId
let IdClassDefinitionAbstract* = "654fbb281446e19b38225236".parseId.RoleId
let IdClassDefinitionInterface* = "654fbb281446e19b38225239".parseId.RoleId
Expand Down Expand Up @@ -205,9 +210,6 @@ let IdIRoleDescriptor* = "654fbb281446e19b3822524c".parseId.ClassId

# new ids

let Id654fbb281446e19b3822524f* = "654fbb281446e19b3822524f".parseId
let Id654fbb281446e19b38225250* = "654fbb281446e19b38225250".parseId
let Id654fbb281446e19b38225251* = "654fbb281446e19b38225251".parseId
let Id654fbb281446e19b38225252* = "654fbb281446e19b38225252".parseId
let Id654fbb281446e19b38225253* = "654fbb281446e19b38225253".parseId
let Id654fbb281446e19b38225254* = "654fbb281446e19b38225254".parseId
Expand All @@ -226,7 +228,6 @@ let Id654fbb281446e19b38225260* = "654fbb281446e19b38225260".parseId
let Id654fbb281446e19b38225261* = "654fbb281446e19b38225261".parseId
let Id654fbb281446e19b38225262* = "654fbb281446e19b38225262".parseId
let Id654fbb281446e19b38225263* = "654fbb281446e19b38225263".parseId
let Id654fbb281446e19b38225264* = "654fbb281446e19b38225264".parseId

# import strformat
# for i in 0..100:
Expand Down
Loading

0 comments on commit 5d48acc

Please sign in to comment.