From 1af6d4d23c24199fa693d085ac255b9e1b6e7247 Mon Sep 17 00:00:00 2001 From: LordBaryhobal Date: Sun, 19 May 2024 12:47:52 +0200 Subject: [PATCH] added xml-loader --- gallery/test.json | 105 +++++++++++++++++++++++++++++++++++++++++++++ gallery/test.pdf | Bin 30098 -> 41228 bytes gallery/test.typ | 17 ++++++-- gallery/test.xml | 68 +++++++++++++++++++++++++++++ src/schema.typ | 7 +-- src/xml-loader.typ | 100 ++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 288 insertions(+), 9 deletions(-) create mode 100644 gallery/test.json create mode 100644 gallery/test.xml create mode 100644 src/xml-loader.typ diff --git a/gallery/test.json b/gallery/test.json new file mode 100644 index 0000000..fc15e6d --- /dev/null +++ b/gallery/test.json @@ -0,0 +1,105 @@ +{ + "structures": { + "main": { + "bits": 32, + "ranges": { + "31-28": { + "name": "cond" + }, + "27": { + "name": "0" + }, + "26": { + "name": "1" + }, + "25": { + "name": "I" + }, + "24": { + "name": "P", + "description": "pre / post indexing bit", + "values": { + "0": "post, add offset after transfer", + "1": "pre, add offset before transfer" + } + }, + "23": { + "name": "U", + "description": "up / down bit", + "values": { + "0": "down, subtract offset from base", + "1": "up, addition offset to base" + } + }, + "22": { + "name": "B", + "description": "byte / word bit", + "values": { + "0": "transfer word quantity", + "1": "transfer byte quantity" + } + }, + "21": { + "name": "W", + "description": "write-back bit", + "values": { + "0": "no write-back", + "1": "write address into base" + } + }, + "20": { + "name": "L", + "description": "load / store bit", + "values": { + "0": "store to memory", + "1": "load from memory" + } + }, + "19-16": { + "name": "Rn", + "description": "base register" + }, + "15-12": { + "name": "Rd", + "description": "source / destination register" + }, + "11-0": { + "name": "offset", + "depends-on": "25", + "values": { + "0": { + "description": "offset is an immediate value", + "structure": "immediateOffset" + }, + "1": { + "description": "offset is a register", + "structure": "registerOffset" + } + } + } + } + }, + "immediateOffset": { + "bits": 12, + "ranges": { + "11-0": { + "name": "12-bit immediate offset", + "description": "unsigned number" + } + } + }, + "registerOffset": { + "bits": 12, + "ranges": { + "11-4": { + "name": "shift", + "description": "shift applied to Rm" + }, + "3-0": { + "name": "Rm", + "description": "offset register" + } + } + } + } +} diff --git a/gallery/test.pdf b/gallery/test.pdf index b9d3795853811efb0a92fd846f7b82554a76adda..cac2ecf5152defeb38a645342adc53094320c56f 100644 GIT binary patch delta 10454 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 diff --git a/gallery/test.typ b/gallery/test.typ index 16b0d90..5cb1589 100644 --- a/gallery/test.typ +++ b/gallery/test.typ @@ -1,7 +1,16 @@ #import "../src/lib.typ": * -#let test = schema.load("/gallery/test.yaml") -#schema.render(test, config: config.blueprint( - full-page: true, - default-font-family: "Ubuntu Mono" +#let test-yaml = schema.load("/gallery/test.yaml") +#schema.render(test-yaml, config: config.config( + full-page: true +)) + +#let test-json = schema.load("/gallery/test.json") +#schema.render(test-json, config: config.blueprint( + full-page: true +)) + +#let test-xml = schema.load("/gallery/test.xml") +#schema.render(test-xml, config: config.dark( + full-page: true )) \ No newline at end of file diff --git a/gallery/test.xml b/gallery/test.xml new file mode 100644 index 0000000..ab92e22 --- /dev/null +++ b/gallery/test.xml @@ -0,0 +1,68 @@ + + + + + + + + pre / post indexing bit + + post, add offset after transfer + pre, add offset before transfer + + + + up / down bit + + down, subtract offset from base + up, addition offset to base + + + + byte / word bit + + transfer word quantity + transfer byte quantity + + + + write-back bit + + no write-back + write address into base + + + + load / store bit + + store to memory + load from memory + + + + base register + + + source / destination register + + + + offset is an immediate value + offset is a register + + + + + + unsigned number + + + + + shift applied to Rm + + + offset register + + + \ No newline at end of file diff --git a/src/schema.typ b/src/schema.typ index 8abd894..335b887 100644 --- a/src/schema.typ +++ b/src/schema.typ @@ -1,13 +1,10 @@ #import "config.typ" as conf #import "renderer.typ" #import "structure.typ" +#import "xml-loader.typ" #let valid-extensions = ("yaml", "json", "xml") -#let parse-xml(path) = { - panic("TODO") -} - #let parse-file(path) = { let ext = path.split(".").last() @@ -22,7 +19,7 @@ } else if ext == "json" { return json(path) } else if ext == "xml" { - return parse-xml(path) + return xml-loader.load(path) } } diff --git a/src/xml-loader.typ b/src/xml-loader.typ new file mode 100644 index 0000000..ca7213a --- /dev/null +++ b/src/xml-loader.typ @@ -0,0 +1,100 @@ +#let find(elmt, tag) = { + if not "children" in elmt { + return none + } + + return elmt.children.find(e => "tag" in e and e.tag == tag) +} + +#let find-all(elmt, tag) = { + if not "children" in elmt { + return () + } + + return elmt.children.filter(e => "tag" in e and e.tag == tag) +} + +#let parse-values(elmt) = { + let values = (:) + let case-elmts = find-all(elmt, "case") + + for case-elmt in case-elmts { + let val = case-elmt.attrs.value + let desc = case-elmt.children.first() + let struct = none + if "structure" in case-elmt.attrs { + struct = case-elmt.attrs.structure + } + + values.insert(val, + if struct != none { + ( + description: desc, + structure: struct + ) + } else { + desc + } + ) + } + + return values +} + +#let parse-range(elmt) = { + let range_ = ( + name: elmt.attrs.name + ) + let desc = none + if "children" in elmt { + desc = find(elmt, "description") + } + + if desc != none { + range_.insert("description", desc.children.first()) + } + + let values-elmt = find(elmt, "values") + if values-elmt != none { + range_.insert("values", parse-values(values-elmt)) + } + + if "depends-on" in elmt.attrs { + range_.insert("depends-on", elmt.attrs.depends-on) + } + + return range_ +} + +#let parse-structure(elmt) = { + let ranges = (:) + let range-elmts = elmt.children.filter(e => "tag" in e and e.tag == "range") + + for range-elmt in range-elmts { + let span = range-elmt.attrs.end + "-" + range-elmt.attrs.start + ranges.insert(span, parse-range(range-elmt)) + } + + return ( + bits: elmt.attrs.bits, + ranges: ranges + ) +} + +#let load(path) = { + let content = xml(path).first() + let struct-elmts = content.children.filter(e => "tag" in e and e.tag == "structure") + + let structures = (:) + + for struct-elmt in struct-elmts { + structures.insert( + struct-elmt.attrs.id, + parse-structure(struct-elmt) + ) + } + + return ( + structures: structures + ) +} \ No newline at end of file