diff --git a/spec/chip.typ b/spec/chip.typ index c694db90a..ad7e1a7eb 100644 --- a/spec/chip.typ +++ b/spec/chip.typ @@ -1,4 +1,4 @@ -#import "expr.typ": expr_to_code, expr_to_math +#import "expr.typ": expr_to_code, expr_to_math, type_to_code /// Computes the total number of variables in a `chip` #let total_nr_variables(chip) = { @@ -13,7 +13,14 @@ .filter(pair => pair.at(0) in config.variables.categories.instantiated) .map(pair => pair.at(1)) .flatten() - .map(var => config.variables.types.filter(type => type.label == var.type).at(0).subtypes.len()) + .map(var => { + let (label, factor) = if type(var.type) == array { + (var.type.at(0), var.type.at(1)) + } else { + (var.type, 1) + } + config.variables.types.filter(type => type.label == label).first().subtypes.len() * factor + }) .sum() } @@ -30,7 +37,7 @@ ..for (cat, vars) in chip.variables.pairs() { ([#emph(cat)], [], [], table.hline(stroke: .6pt)) for var in vars { - ([#raw(var.name)], [#raw(var.type)], [#eval(var.desc, mode: "markup")]) + ([#raw(var.name)], [#type_to_code(var.type)], [#eval(var.desc, mode: "markup")]) for (i, poly) in var.at("polys", default: ()).enumerate() { (if i == 0 { emph[def] }, [], expr_to_math(("=", ("idx", var.name, i), poly))) } diff --git a/spec/expr.typ b/spec/expr.typ index df1ddb2e6..ab5be4704 100644 --- a/spec/expr.typ +++ b/spec/expr.typ @@ -117,3 +117,24 @@ var: v => if v.len() == 1 { $#v$ } else { $#raw(v)$ }, num: n => math.equation[#n], ) + +// Check that a type expression is structurally valid, without validating against a set of known base types +#let check_array_type(typ) = { + assert(type(typ.at(0)) == str, message: "Array types need to have a regular type as base") + assert(type(typ.at(1)) == int, message: "Array types need to have a constant dimension") +} + +// Render a type to code +#let type_to_code(typ) = { + if type(typ) == array { + check_array_type(typ) + return raw(typ.at(0) + "[" + str(typ.at(1)) + "]") + } else if type(typ) == string { + return raw(typ) + } else { + assert(false, message: "Unknown format for type: " + repr(typ)) + } +} + +// Render a type to math +#let type_to_math(typ) = render_type_to_code(typ) // The code version looks reasonable enough in math too diff --git a/spec/src.typ b/spec/src.typ index f791bc1ca..75a81a5f9 100644 --- a/spec/src.typ +++ b/spec/src.typ @@ -38,12 +38,16 @@ assert(category in config.variables.categories.all) } + let all_labels = config.variables.types.map(type => type.label); for var in chip.variables.values().flatten() { + let type_label = if type(var.type) == array { + var.type.at(0) + } else { + var.type + } + // Check that all variable types are valid - assert( - var.type in config.variables.types.map(type => type.label), - message: "found invalid var type:" + var.type, - ) + assert(type_label in all_labels, message: "found invalid var type:" + repr(var.type)) } } diff --git a/spec/src/config.toml b/spec/src/config.toml index 1977b9155..29c0b9d83 100644 --- a/spec/src/config.toml +++ b/spec/src/config.toml @@ -81,33 +81,6 @@ desc = """\ The `Word` is the least significant digit. """ -# TODO: Having to define these manually will get tedious -[[variables.types]] -label = "Bit[3]" -subtypes = ["Bit", "Bit", "Bit"] -desc = "Three bits" - -[[variables.types]] -label = "Byte[2]" -subtypes = ["Byte", "Byte"] -desc = "Two bytes" - -[[variables.types]] -label = "Byte[8]" -subtypes = ["Byte", "Byte", "Byte", "Byte", "Byte", "Byte", "Byte", "Byte"] -desc = "Eight bytes" - -[[variables.types]] -label = "Half[3]" -subtypes = ["Half", "Half", "Half"] -desc = "Three halfwords" - -[[variables.types]] -label = "Half[8]" -subtypes = ["Half", "Half", "Half", "Half", "Half", "Half", "Half", "Half"] -desc = "Eight halfwords" - - [variables.categories] all = ["input", "output", "auxiliary", "virtual", "multiplicity"] instantiated = ["input", "output", "auxiliary", "multiplicity"]