Font editer coming a long. first font is looking good. some parser changes to accomodate any string as record fields. other stuff
This commit is contained in:
parent
e3b8930111
commit
d79166a5bc
6 changed files with 4987 additions and 25 deletions
13
src/ast.ts
13
src/ast.ts
|
|
@ -220,7 +220,7 @@ export function prettyPrint(ast: AST, indent = 0): string {
|
|||
const parts = ast.entries.map(entry =>
|
||||
entry.kind === 'spread'
|
||||
? `...${prettyPrint(entry.expr, indent + 1)}`
|
||||
: `${entry.key} = ${prettyPrint(entry.value, indent + 1)}`
|
||||
: `${needsQuotes(entry.key) ? `"${entry.key}"` : entry.key} = ${prettyPrint(entry.value, indent + 1)}`
|
||||
);
|
||||
if (parts.length <= 1) return `{ ${parts.join(', ')} }`;
|
||||
const inner = parts.map(p => `${' '.repeat(indent + 1)}${p}`).join(',\n');
|
||||
|
|
@ -238,11 +238,12 @@ export function prettyPrint(ast: AST, indent = 0): string {
|
|||
}
|
||||
|
||||
case 'record-access':
|
||||
return `${prettyPrint(ast.record, indent)}.${ast.field}`;
|
||||
const field = needsQuotes(ast.field) ? `"${ast.field}"` : ast.field;
|
||||
return `${prettyPrint(ast.record, indent)}.${field}`;
|
||||
|
||||
case 'record-update': {
|
||||
const updates = Object.entries(ast.updates)
|
||||
.map(([k, v]) => `${k} = ${prettyPrint(v, indent)}`)
|
||||
.map(([k, v]) => `${needsQuotes(k) ? `"${k}"` : k} = ${prettyPrint(v, indent)}`)
|
||||
.join(', ');
|
||||
return `${prettyPrint(ast.record, indent)}.{ ${updates} }`
|
||||
}
|
||||
|
|
@ -298,7 +299,7 @@ function prettyPrintPattern(pattern: Pattern): string {
|
|||
|
||||
case 'record':
|
||||
const fields = Object.entries(pattern.fields)
|
||||
.map(([k, p]) => `${k} = ${prettyPrintPattern(p)}`)
|
||||
.map(([k, p]) => `${needsQuotes(k) ? `"${k}"` : k} = ${prettyPrintPattern(p)}`)
|
||||
.join(', ');
|
||||
|
||||
return `{${fields}}`;
|
||||
|
|
@ -306,3 +307,7 @@ function prettyPrintPattern(pattern: Pattern): string {
|
|||
return `Unknown AST kind: ${(pattern as any).kind}`
|
||||
}
|
||||
}
|
||||
|
||||
function needsQuotes(key: string): boolean {
|
||||
return !/^[a-z_][a-zA-Z0-9_]*$/.test(key);
|
||||
}
|
||||
|
|
|
|||
4942
src/cg/06-font.cg
Normal file
4942
src/cg/06-font.cg
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -51,12 +51,15 @@ fontEditor = config \
|
|||
| _ \ { state = state, emit = [] },
|
||||
|
||||
view = state emit \
|
||||
tileSize = 50;
|
||||
tileSize = 52;
|
||||
|
||||
tileView = g \
|
||||
glyph = g.value;
|
||||
key = g.key;
|
||||
scale = max 1 (floor (min (tileSize / glyph.w) (tileSize / glyph.h)) - 2);
|
||||
# scale = max 1 (floor (min (tileSize / glyph.w) (tileSize / glyph.h)) - 2);
|
||||
scale = 4;
|
||||
x = floor ((tileSize - glyph.w * scale) / 2);
|
||||
|
||||
ui.clickable {
|
||||
onClick = \ editGlyph (c.path & ".glyphs." & key),
|
||||
child = ui.stack {
|
||||
|
|
@ -64,30 +67,41 @@ fontEditor = config \
|
|||
ui.rect { w = tileSize, h = tileSize, strokeWidth = 1, strokeColor = "#fff" },
|
||||
# center tileSize tileSize (glyphView { glyph = glyph, scale = scale })
|
||||
ui.positioned {
|
||||
x = scale, y = scale,
|
||||
x = 3 * scale, y = scale,
|
||||
child = glyphView { glyph = glyph, scale = scale }
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
headerHeight = 30;
|
||||
|
||||
header = ui.row {
|
||||
gap = 10,
|
||||
children = [
|
||||
inputButton {
|
||||
h = headerHeight,
|
||||
key = "new-glyph-button",
|
||||
label = "New Glyph",
|
||||
onSubmit = key \ rebindAt (c.path & ".glyphs." & key) { w = 5, h = 7, map = [] }
|
||||
onSubmit = key \ rebindAt (c.path & ".glyphs." & key) { w = 7, h = 12, map = [] }
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
ui.column {
|
||||
gap = 2,
|
||||
children = [
|
||||
header,
|
||||
...map tileView (entries state.glyphs)
|
||||
]
|
||||
}
|
||||
perRow = floor (ctx.w / tileSize) - 1;
|
||||
|
||||
grid = ui.stack {
|
||||
children = mapWithIndex (g idx \
|
||||
x = (idx % perRow) * tileSize + 2 * (idx % perRow);
|
||||
y = (floor (idx / perRow)) * tileSize + 2 * (floor (idx / perRow));
|
||||
|
||||
ui.positioned {
|
||||
x = x,
|
||||
y = y,
|
||||
child = tileView g
|
||||
}) (entries state.glyphs)
|
||||
};
|
||||
|
||||
ui.column { gap = 2, children = [ header, grid ] }
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ pixelEditor = config \
|
|||
{ state = newState, emit = saveGlyph newState });
|
||||
|
||||
existing = eval! (c.path);
|
||||
_ = debug! "existing" existing;
|
||||
|
||||
# return App
|
||||
{
|
||||
|
|
@ -50,16 +51,16 @@ pixelEditor = config \
|
|||
init = existing
|
||||
| Value v \ {
|
||||
map = v.map,
|
||||
pixelWidth = 5,
|
||||
pixelHeight = 7,
|
||||
pixelWidth = v.w,
|
||||
pixelHeight = v.h,
|
||||
cellSize = 30,
|
||||
selectedRow = 0,
|
||||
selectedCol = 0
|
||||
}
|
||||
| _ \ {
|
||||
map = [],
|
||||
pixelWidth = 5,
|
||||
pixelHeight = 7,
|
||||
pixelWidth = 7,
|
||||
pixelHeight = 12,
|
||||
cellSize = 30,
|
||||
selectedRow = 0,
|
||||
selectedCol = 0
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ export function compile(ast: AST, ctx: CompileCtx = defaultCtx): string {
|
|||
const parts = ast.entries.map(entry =>
|
||||
entry.kind === 'spread'
|
||||
? `...${compile(entry.expr, ctx)}`
|
||||
: `${sanitizeName(entry.key)}: ${compile(entry.value, ctx)}`
|
||||
: `${JSON.stringify(entry.key)}: ${compile(entry.value, ctx)}`
|
||||
)
|
||||
return `({${parts.join(', ')}})`;
|
||||
}
|
||||
|
|
@ -69,11 +69,11 @@ export function compile(ast: AST, ctx: CompileCtx = defaultCtx): string {
|
|||
}
|
||||
|
||||
case 'record-access':
|
||||
return `${compile(ast.record, ctx)}.${sanitizeName(ast.field)}`;
|
||||
return `${compile(ast.record, ctx)}[${JSON.stringify(ast.field)}]`;
|
||||
|
||||
case 'record-update':
|
||||
const updates = Object.entries(ast.updates)
|
||||
.map(([k, v]) => `${sanitizeName(k)}: ${compile(v, ctx)}`);
|
||||
.map(([k, v]) => `${JSON.stringify(k)}: ${compile(v, ctx)}`);
|
||||
return `({...${compile(ast.record, ctx)}, ${updates.join(', ')}})`;
|
||||
|
||||
case 'let': {
|
||||
|
|
@ -207,7 +207,7 @@ function compilePattern(pattern: Pattern, expr: string): { condition: string, bi
|
|||
let condition = 'true';
|
||||
const bindings: string[] = [];
|
||||
for (const [field, fieldPattern] of Object.entries(pattern.fields)) {
|
||||
const sub = compilePattern(fieldPattern, `${expr}.${sanitizeName(field)}`);
|
||||
const sub = compilePattern(fieldPattern, `${expr}[${JSON.stringify(field)}]`);
|
||||
if (sub.condition !== 'true') condition += ` && ${sub.condition}`;
|
||||
bindings.push(...sub.bindings);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,11 +44,11 @@ export class Parser {
|
|||
|
||||
private expectIdent(): Token {
|
||||
const token = this.current();
|
||||
if (token.kind === 'ident' || token.kind === 'type-ident') {
|
||||
if (token.kind === 'ident' || token.kind === 'type-ident' || token.kind === 'string') {
|
||||
this.advance();
|
||||
return token;
|
||||
}
|
||||
throw this.error(`Expected identifier, got ${token.kind}`);
|
||||
throw ParseError(`Expected identifier, got ${token.kind}`);
|
||||
}
|
||||
|
||||
private getPos(token: Token) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue