initial commit
This commit is contained in:
94
misc/uml/parser.typ
Normal file
94
misc/uml/parser.typ
Normal file
@@ -0,0 +1,94 @@
|
||||
#import "uml.typ"
|
||||
|
||||
#let parse-args(data) = {
|
||||
let args = data.split(",").map(a => a.trim()).filter(a => a.len() != 0)
|
||||
let res
|
||||
if ":" in data {
|
||||
res = (:)
|
||||
} else {
|
||||
res = ()
|
||||
}
|
||||
|
||||
for arg in args {
|
||||
let parts = arg.split(":")
|
||||
let arg-name = none
|
||||
let arg-type
|
||||
if parts.len() == 1 {
|
||||
if type(res) == dictionary {
|
||||
panic("Cannot mix named and unnamed arguments")
|
||||
}
|
||||
arg-type = parts.first().trim()
|
||||
res.push(arg-type)
|
||||
} else {
|
||||
arg-name = parts.first().trim()
|
||||
arg-type = parts.slice(1).join(":").trim()
|
||||
res.insert(arg-name, arg-type)
|
||||
}
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
#let parse(data) = {
|
||||
let elements = ()
|
||||
|
||||
if type(data) == raw or type(data) == content {
|
||||
data = data.text
|
||||
}
|
||||
|
||||
let classes = data.matches(regex("(?ms)(abstract class|class|interface) (.*?)\s*\{(.*?)\}"))
|
||||
|
||||
for class in classes {
|
||||
let family-name = class.captures.first()
|
||||
let family = (
|
||||
class: none,
|
||||
"abstract class": uml.abstract,
|
||||
"interface": uml.interface,
|
||||
"enum": uml.enum,
|
||||
).at(family-name)
|
||||
|
||||
let name = class.captures.at(1)
|
||||
let class-data = class.captures.last().trim()
|
||||
|
||||
let members = class-data.matches(regex("(?m)^\s*(.*?)\s*(:\s*([^:]*?))?$")).filter(m => m.text.len() != 0)
|
||||
let attributes = ()
|
||||
let methods = ()
|
||||
for member in members {
|
||||
let member-name = member.captures.first()
|
||||
let val-type = member.captures.last()
|
||||
let visibility = none
|
||||
|
||||
if member-name.starts-with(regex("\+|-|~|#")) {
|
||||
let vis = member-name.first()
|
||||
member-name = member-name.slice(1)
|
||||
visibility = (
|
||||
"+": uml.public,
|
||||
"-": uml.private,
|
||||
"~": uml.package,
|
||||
"#": uml.protected
|
||||
).at(vis)
|
||||
}
|
||||
|
||||
if member-name.ends-with(")") {
|
||||
let func = member-name.match(regex("^(.*?)\((.*)\)$"))
|
||||
member-name = func.captures.first()
|
||||
let args = parse-args(func.captures.last())
|
||||
methods += uml.method(member-name, visibility, val-type, args)
|
||||
} else {
|
||||
attributes += uml.attr(member-name, visibility, val-type)
|
||||
}
|
||||
}
|
||||
|
||||
elements += uml.class(name, family, attributes + methods)
|
||||
}
|
||||
|
||||
let defaults = (:)
|
||||
let params = data.matches(regex("(?m)^\s*@\s*(.*?)\s*=\s*(.*)\s*$"))
|
||||
for param in params {
|
||||
let key = param.captures.first()
|
||||
let value = eval(param.captures.last(), scope: (uml: uml))
|
||||
defaults.insert(key, value)
|
||||
}
|
||||
|
||||
return uml.diagram(elements, defaults)
|
||||
}
|
Reference in New Issue
Block a user