Compare commits

..

2 Commits

Author SHA1 Message Date
83d7a8d85b
fixed dependency numbering error 2024-05-19 13:27:52 +02:00
1af6d4d23c
added xml-loader 2024-05-19 12:47:52 +02:00
7 changed files with 299 additions and 17 deletions

105
gallery/test.json Normal file
View File

@ -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"
}
}
}
}
}

Binary file not shown.

View File

@ -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
))

68
gallery/test.xml Normal file
View File

@ -0,0 +1,68 @@
<schema>
<structure id="main" bits="32">
<range start="28" end="31" name="cond"></range>
<range start="27" end="27" name="0"></range>
<range start="26" end="26" name="1"></range>
<range start="25" end="25" name="I"></range>
<range start="24" end="24" name="P">
<description>pre / post indexing bit</description>
<values>
<case value="0">post, add offset after transfer</case>
<case value="1">pre, add offset before transfer</case>
</values>
</range>
<range start="23" end="23" name="U">
<description>up / down bit</description>
<values>
<case value="0">down, subtract offset from base</case>
<case value="1">up, addition offset to base</case>
</values>
</range>
<range start="22" end="22" name="B">
<description>byte / word bit</description>
<values>
<case value="0">transfer word quantity</case>
<case value="1">transfer byte quantity</case>
</values>
</range>
<range start="21" end="21" name="W">
<description>write-back bit</description>
<values>
<case value="0">no write-back</case>
<case value="1">write address into base</case>
</values>
</range>
<range start="20" end="20" name="L">
<description>load / store bit</description>
<values>
<case value="0">store to memory</case>
<case value="1">load from memory</case>
</values>
</range>
<range start="16" end="19" name="Rn">
<description>base register</description>
</range>
<range start="12" end="15" name="Rd">
<description>source / destination register</description>
</range>
<range start="0" end="11" name="offset" depends-on="25">
<values>
<case value="0" structure="immediateOffset">offset is an immediate value</case>
<case value="1" structure="registerOffset">offset is a register</case>
</values>
</range>
</structure>
<structure id="immediateOffset" bits="12">
<range start="0" end="11" name="12-bit immediate offset">
<description>unsigned number</description>
</range>
</structure>
<structure id="registerOffset" bits="12">
<range start="4" end="11" name="shift">
<description>shift applied to Rm</description>
</range>
<range start="0" end="3" name="Rm">
<description>offset register</description>
</range>
</structure>
</schema>

View File

@ -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)
}
}

View File

@ -1,4 +1,4 @@
#import "range.typ"
#import "range.typ" as rng
#import "util.typ"
#let make(
@ -20,30 +20,33 @@
let ranges = (:)
for (range-span, range-data) in data.ranges {
let (start, end) = range.parse-span(str(range-span))
let (start, end) = rng.parse-span(str(range-span))
ranges.insert(
range.key(start, end),
range.load(start, end, range-data)
rng.key(start, end),
rng.load(start, end, range-data)
)
}
for range_ in ranges.values() {
let ranges2 = (:)
for (k, range_) in ranges {
if range_.values != none and range_.depends-on != none {
let depends-key = range.key(..range_.depends-on)
let depends-key = rng.key(..range_.depends-on)
let depends-range = ranges.at(depends-key)
let bits = range.bits(depends-range)
let bits = rng.bits(depends-range)
let values = (:)
for (v, d) in range_.values {
v = util.z-fill(str(int(v)), bits)
values.insert(v, d)
}
range_.values = values
}
ranges2.insert(k, range_)
}
return make(
id,
int(data.bits),
ranges,
ranges2,
start: data.at("start", default: 0)
)
}

100
src/xml-loader.typ Normal file
View File

@ -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
)
}