more size opts

This commit is contained in:
Jakub Doka 2024-10-10 09:51:03 +02:00
parent 54a7f85978
commit c31d1dcb9c
No known key found for this signature in database
GPG key ID: C6E9A89936B8C143
6 changed files with 96 additions and 71 deletions

1
Cargo.lock generated
View file

@ -821,7 +821,6 @@ name = "wasm-hbfmt"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"hblang", "hblang",
"log",
] ]
[[package]] [[package]]

View file

@ -45,6 +45,8 @@ div.preview {
display: flex; display: flex;
gap: var(--small-gap); gap: var(--small-gap);
} }
margin: var(--small-gap) 0px;
} }
form { form {
@ -63,16 +65,22 @@ form {
} }
pre,
textarea { textarea {
outline: none; outline: none;
border: none; border: none;
background: var(--secondary); background: var(--secondary);
padding: var(--small-gap); padding: var(--small-gap);
padding-top: calc(var(--small-gap) * 1.5); padding-top: calc(var(--small-gap) * 1.5);
margin: var(--small-gap) 0px;
font-family: var(--monospace); font-family: var(--monospace);
resize: none; resize: none;
}
pre {
background: var(--secondary);
padding: var(--small-gap);
padding-top: calc(var(--small-gap) * 1.5);
margin: 0px;
font-family: var(--monospace);
tab-size: 4; tab-size: 4;
} }

View file

@ -131,8 +131,6 @@ impl Page for Post {
required maxlength=MAX_POSTNAME_LENGTH> required maxlength=MAX_POSTNAME_LENGTH>
<textarea name="code" placeholder="code" rows=1 required>code</textarea> <textarea name="code" placeholder="code" rows=1 required>code</textarea>
<input type="submit" value="submit"> <input type="submit" value="submit">
<input type="button" "hx-get"="/post-preview" "hx-swap"="outherHTML"
"hx-target"="postForm" value="preview">
</form> </form>
!{include_str!("post-page.html")} !{include_str!("post-page.html")}
} }

View file

@ -7,5 +7,4 @@ edition = "2021"
crate-type = ["cdylib"] crate-type = ["cdylib"]
[dependencies] [dependencies]
hblang = { version = "0.1.0", path = "../../hblang", default-features = false } hblang = { version = "0.1.0", path = "../../hblang", default-features = false, features = ["no_log"] }
log = { version = "0.4.22", features = ["max_level_off"] }

View file

@ -22,3 +22,4 @@ optional = true
default = ["std", "opts"] default = ["std", "opts"]
std = [] std = []
opts = ["regalloc2"] opts = ["regalloc2"]
no_log = ["log/max_level_off"]

View file

@ -73,6 +73,7 @@ pub struct Formatter<'a> {
depth: usize, depth: usize,
} }
// we exclusively use `write_str` to reduce bloat
impl<'a> Formatter<'a> { impl<'a> Formatter<'a> {
pub fn new(source: &'a str) -> Self { pub fn new(source: &'a str) -> Self {
Self { source, depth: 0 } Self { source, depth: 0 }
@ -106,11 +107,12 @@ impl<'a> Formatter<'a> {
let mut first = true; let mut first = true;
for expr in list { for expr in list {
if !core::mem::take(&mut first) { if !core::mem::take(&mut first) {
write!(f, "{sep} ")?; f.write_str(sep)?;
f.write_str(" ")?;
} }
first = !fmt(self, expr, f)?; first = !fmt(self, expr, f)?;
} }
return write!(f, "{end}"); return f.write_str(end);
} }
writeln!(f)?; writeln!(f)?;
@ -118,24 +120,24 @@ impl<'a> Formatter<'a> {
let res = (|| { let res = (|| {
for (i, stmt) in list.iter().enumerate() { for (i, stmt) in list.iter().enumerate() {
for _ in 0..self.depth { for _ in 0..self.depth {
write!(f, "\t")?; f.write_str("\t")?;
} }
let add_sep = fmt(self, stmt, f)?; let add_sep = fmt(self, stmt, f)?;
if add_sep { if add_sep {
write!(f, "{sep}")?; f.write_str(sep)?;
} }
if let Some(expr) = list.get(i + 1) if let Some(expr) = list.get(i + 1)
&& let Some(rest) = self.source.get(expr.posi() as usize..) && let Some(rest) = self.source.get(expr.posi() as usize..)
{ {
if insert_needed_semicolon(rest) { if insert_needed_semicolon(rest) {
write!(f, ";")?; f.write_str(";")?;
} }
if preserve_newlines(&self.source[..expr.posi() as usize]) > 1 { if preserve_newlines(&self.source[..expr.posi() as usize]) > 1 {
writeln!(f)?; f.write_str("\n")?;
} }
} }
if add_sep { if add_sep {
writeln!(f)?; f.write_str("\n")?;
} }
} }
Ok(()) Ok(())
@ -143,9 +145,9 @@ impl<'a> Formatter<'a> {
self.depth -= 1; self.depth -= 1;
for _ in 0..self.depth { for _ in 0..self.depth {
write!(f, "\t")?; f.write_str("\t")?;
} }
write!(f, "{end}")?; f.write_str(end)?;
res res
} }
@ -156,9 +158,9 @@ impl<'a> Formatter<'a> {
cond: impl FnOnce(&Expr) -> bool, cond: impl FnOnce(&Expr) -> bool,
) -> fmt::Result { ) -> fmt::Result {
if cond(expr) { if cond(expr) {
write!(f, "(")?; f.write_str("(")?;
self.fmt(expr, f)?; self.fmt(expr, f)?;
write!(f, ")") f.write_str(")")
} else { } else {
self.fmt(expr, f) self.fmt(expr, f)
} }
@ -181,33 +183,40 @@ impl<'a> Formatter<'a> {
match *expr { match *expr {
Expr::Ct { value, .. } => { Expr::Ct { value, .. } => {
write!(f, "$: ")?; f.write_str("$: ")?;
self.fmt(value, f) self.fmt(value, f)
} }
Expr::String { literal, .. } => write!(f, "{literal}"), Expr::String { literal, .. } => f.write_str(literal),
Expr::Comment { literal, .. } => write!(f, "{literal}"), Expr::Comment { literal, .. } => f.write_str(literal),
Expr::Mod { path, .. } => write!(f, "@use(\"{path}\")"), Expr::Mod { path, .. } => write!(f, "@use(\"{path}\")"),
Expr::Field { target, name: field, .. } => { Expr::Field { target, name: field, .. } => {
self.fmt_paren(target, f, postfix)?; self.fmt_paren(target, f, postfix)?;
write!(f, ".{field}") f.write_str(".")?;
f.write_str(field)
} }
Expr::Directive { name, args, .. } => { Expr::Directive { name, args, .. } => {
write!(f, "@{name}(")?; f.write_str("@")?;
f.write_str(name)?;
f.write_str("(")?;
self.fmt_list(f, false, ")", ",", args, Self::fmt) self.fmt_list(f, false, ")", ",", args, Self::fmt)
} }
Expr::Struct { fields, trailing_comma, packed, .. } => { Expr::Struct { fields, trailing_comma, packed, .. } => {
if packed { if packed {
write!(f, "packed ")?; f.write_str("packed ")?;
} }
write!(f, "struct {{")?; write!(f, "struct {{")?;
self.fmt_list_low(f, trailing_comma, "}", ",", fields, |s, field, f| { self.fmt_list_low(f, trailing_comma, "}", ",", fields, |s, field, f| {
match field { match field {
CommentOr::Or(StructField { name, ty, .. }) => { CommentOr::Or(StructField { name, ty, .. }) => {
write!(f, "{name}: ")?; f.write_str(name)?;
f.write_str(": ")?;
s.fmt(ty, f)? s.fmt(ty, f)?
} }
CommentOr::Comment { literal, .. } => writeln!(f, "{literal}")?, CommentOr::Comment { literal, .. } => {
f.write_str(literal)?;
f.write_str("\n")?;
}
} }
Ok(field.or().is_some()) Ok(field.or().is_some())
}) })
@ -216,7 +225,7 @@ impl<'a> Formatter<'a> {
if let Some(ty) = ty { if let Some(ty) = ty {
self.fmt_paren(ty, f, unary)?; self.fmt_paren(ty, f, unary)?;
} }
write!(f, ".{{")?; f.write_str(".{")?;
self.fmt_list( self.fmt_list(
f, f,
trailing_comma, trailing_comma,
@ -224,12 +233,12 @@ impl<'a> Formatter<'a> {
",", ",",
fields, fields,
|s: &mut Self, CtorField { name, value, .. }: &_, f| { |s: &mut Self, CtorField { name, value, .. }: &_, f| {
if matches!(value, Expr::Ident { name: n, .. } if name == n) { f.write_str(name)?;
write!(f, "{name}") if !matches!(value, Expr::Ident { name: n, .. } if name == n) {
} else { f.write_str(": ")?;
write!(f, "{name}: ")?; s.fmt(value, f)?;
s.fmt(value, f)
} }
Ok(())
}, },
) )
} }
@ -237,74 +246,78 @@ impl<'a> Formatter<'a> {
if let Some(ty) = ty { if let Some(ty) = ty {
self.fmt_paren(ty, f, unary)?; self.fmt_paren(ty, f, unary)?;
} }
write!(f, ".(")?; f.write_str(".(")?;
self.fmt_list(f, trailing_comma, ")", ",", fields, Self::fmt) self.fmt_list(f, trailing_comma, ")", ",", fields, Self::fmt)
} }
Expr::Slice { item, size, .. } => { Expr::Slice { item, size, .. } => {
write!(f, "[")?; f.write_str("[")?;
self.fmt(item, f)?; self.fmt(item, f)?;
if let Some(size) = size { if let Some(size) = size {
write!(f, "; ")?; f.write_str("; ")?;
self.fmt(size, f)?; self.fmt(size, f)?;
} }
write!(f, "]") f.write_str("]")
} }
Expr::Index { base, index } => { Expr::Index { base, index } => {
self.fmt(base, f)?; self.fmt(base, f)?;
write!(f, "[")?; f.write_str("[")?;
self.fmt(index, f)?; self.fmt(index, f)?;
write!(f, "]") f.write_str("]")
} }
Expr::UnOp { op, val, .. } => { Expr::UnOp { op, val, .. } => {
write!(f, "{op}")?; f.write_str(op.name())?;
self.fmt_paren(val, f, unary) self.fmt_paren(val, f, unary)
} }
Expr::Break { .. } => write!(f, "break"), Expr::Break { .. } => f.write_str("break"),
Expr::Continue { .. } => write!(f, "continue"), Expr::Continue { .. } => f.write_str("continue"),
Expr::If { cond, then, else_, .. } => { Expr::If { cond, then, else_, .. } => {
write!(f, "if ")?; f.write_str("if ")?;
self.fmt(cond, f)?; self.fmt(cond, f)?;
write!(f, " ")?; f.write_str(" ")?;
self.fmt_paren(then, f, consecutive)?; self.fmt_paren(then, f, consecutive)?;
if let Some(e) = else_ { if let Some(e) = else_ {
write!(f, " else ")?; f.write_str(" else ")?;
self.fmt(e, f)?; self.fmt(e, f)?;
} }
Ok(()) Ok(())
} }
Expr::Loop { body, .. } => { Expr::Loop { body, .. } => {
write!(f, "loop ")?; f.write_str("loop ")?;
self.fmt(body, f) self.fmt(body, f)
} }
Expr::Closure { ret, body, args, .. } => { Expr::Closure { ret, body, args, .. } => {
write!(f, "fn(")?; f.write_str("fn(")?;
self.fmt_list(f, false, "", ",", args, |s, arg, f| { self.fmt_list(f, false, "", ",", args, |s, arg, f| {
if arg.is_ct { if arg.is_ct {
write!(f, "$")?; f.write_str("$")?;
} }
write!(f, "{}: ", arg.name)?; f.write_str(arg.name)?;
f.write_str(": ")?;
s.fmt(&arg.ty, f) s.fmt(&arg.ty, f)
})?; })?;
write!(f, "): ")?; f.write_str("): ")?;
self.fmt(ret, f)?; self.fmt(ret, f)?;
write!(f, " ")?; f.write_str(" ")?;
self.fmt_paren(body, f, consecutive)?; self.fmt_paren(body, f, consecutive)?;
Ok(()) Ok(())
} }
Expr::Call { func, args, trailing_comma } => { Expr::Call { func, args, trailing_comma } => {
self.fmt_paren(func, f, postfix)?; self.fmt_paren(func, f, postfix)?;
write!(f, "(")?; f.write_str("(")?;
self.fmt_list(f, trailing_comma, ")", ",", args, Self::fmt) self.fmt_list(f, trailing_comma, ")", ",", args, Self::fmt)
} }
Expr::Return { val: Some(val), .. } => { Expr::Return { val: Some(val), .. } => {
write!(f, "return ")?; f.write_str("return ")?;
self.fmt(val, f) self.fmt(val, f)
} }
Expr::Return { val: None, .. } => write!(f, "return"), Expr::Return { val: None, .. } => f.write_str("return"),
Expr::Ident { name, is_ct: true, .. } => write!(f, "${name}"), Expr::Ident { name, is_ct: true, .. } => {
Expr::Ident { name, is_ct: false, .. } => write!(f, "{name}"), f.write_str("$")?;
f.write_str(name)
}
Expr::Ident { name, is_ct: false, .. } => f.write_str(name),
Expr::Block { stmts, .. } => { Expr::Block { stmts, .. } => {
write!(f, "{{")?; f.write_str("{")?;
self.fmt_list(f, true, "}", "", stmts, Self::fmt) self.fmt_list(f, true, "}", "", stmts, Self::fmt)
} }
Expr::Number { value, radix, .. } => { Expr::Number { value, radix, .. } => {
@ -327,24 +340,26 @@ impl<'a> Formatter<'a> {
unreachable!() unreachable!()
} }
f.write_str(match radix {
Radix::Decimal => "",
Radix::Hex => "0x",
Radix::Octal => "0o",
Radix::Binary => "0b",
})?;
let mut buf = [0u8; 64]; let mut buf = [0u8; 64];
let value = display_radix(radix, value as u64, &mut buf); f.write_str(display_radix(radix, value as u64, &mut buf))
match radix {
Radix::Decimal => write!(f, "{value}"),
Radix::Hex => write!(f, "0x{value}"),
Radix::Octal => write!(f, "0o{value}"),
Radix::Binary => write!(f, "0b{value}"),
}
} }
Expr::Bool { value, .. } => write!(f, "{value}"), Expr::Bool { value, .. } => f.write_str(if value { "true" } else { "false" }),
Expr::Idk { .. } => write!(f, "idk"), Expr::Idk { .. } => f.write_str("idk"),
Expr::BinOp { Expr::BinOp {
left, left,
op: TokenKind::Assign, op: TokenKind::Assign,
right: &Expr::BinOp { left: lleft, op, right }, right: &Expr::BinOp { left: lleft, op, right },
} if left.pos() == lleft.pos() => { } if left.pos() == lleft.pos() => {
self.fmt(left, f)?; self.fmt(left, f)?;
write!(f, " {op}= ")?; f.write_str(" ")?;
f.write_str(op.name())?;
f.write_str("= ")?;
self.fmt(right, f) self.fmt(right, f)
} }
Expr::BinOp { right, op, left } => { Expr::BinOp { right, op, left } => {
@ -362,16 +377,21 @@ impl<'a> Formatter<'a> {
let exact_bound = lexer::Lexer::new(&prev[estimate_bound..]).last().start; let exact_bound = lexer::Lexer::new(&prev[estimate_bound..]).last().start;
prev = &prev[..exact_bound as usize + estimate_bound]; prev = &prev[..exact_bound as usize + estimate_bound];
if preserve_newlines(prev) > 0 { if preserve_newlines(prev) > 0 {
writeln!(f)?; f.write_str("\n")?;
for _ in 0..self.depth + 1 { for _ in 0..self.depth + 1 {
write!(f, "\t")?; f.write_str("\t")?;
} }
write!(f, "{op} ")?; f.write_str(op.name())?;
f.write_str(" ")?;
} else { } else {
write!(f, " {op} ")?; f.write_str(" ")?;
f.write_str(op.name())?;
f.write_str(" ")?;
} }
} else { } else {
write!(f, " {op} ")?; f.write_str(" ")?;
f.write_str(op.name())?;
f.write_str(" ")?;
} }
self.fmt_paren(right, f, pec_miss) self.fmt_paren(right, f, pec_miss)
} }