Fixing bugs. escaping things when pretty printing. adding reflect host function. getting further with tree view
This commit is contained in:
parent
f27b946790
commit
fec18486d8
5 changed files with 165 additions and 73 deletions
|
|
@ -180,7 +180,12 @@ export function prettyPrint(ast: AST, indent = 0): string {
|
|||
case 'literal': {
|
||||
const val = ast.value;
|
||||
if (val.kind === 'string') {
|
||||
return `"${val.value}"`;
|
||||
const escaped = val.value
|
||||
.replace(/\\/g, '\\\\')
|
||||
.replace(/"/g, '\\"')
|
||||
.replace(/\n/g, '\\n')
|
||||
.replace(/\t/g, '\\t');
|
||||
return `"${escaped}"`;
|
||||
}
|
||||
return `${val.value}`;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
paletteState = {
|
||||
query = "",
|
||||
focusedIndex = 0,
|
||||
scrollOffset = 0
|
||||
scrollOffset = 0,
|
||||
opacity = 0.95
|
||||
};
|
||||
|
||||
palette = config \
|
||||
|
|
@ -10,6 +11,13 @@ palette = config \
|
|||
|
||||
results = take 100 (config.search paletteState.query);
|
||||
|
||||
nextSelectable = items index direction \
|
||||
next = index + direction;
|
||||
nth next items
|
||||
| Some (Section _) \ nextSelectable items next direction
|
||||
| Some (Item _) \ next
|
||||
| None \ index;
|
||||
|
||||
effectiveIndex = nth paletteState.focusedIndex results
|
||||
| Some (Section _) \ nextSelectable results paletteState.focusedIndex 1
|
||||
| _ \ paletteState.focusedIndex;
|
||||
|
|
@ -23,13 +31,6 @@ palette = config \
|
|||
contentHeight = windowHeight - (dialogPadding * 2);
|
||||
listHeight = contentHeight - 40;
|
||||
|
||||
nextSelectable = items index direction \
|
||||
next = index + direction;
|
||||
nth next items
|
||||
| Some (Section _) \ nextSelectable items next direction
|
||||
| Some (Item _) \ next
|
||||
| None \ index;
|
||||
|
||||
itemHeight = entry \ entry
|
||||
| Section _ \ sectionHeight
|
||||
| Item _ \ textInputHeight
|
||||
|
|
@ -103,61 +104,65 @@ palette = config \
|
|||
x = (config.viewport.width - windowWidth) / 2,
|
||||
y = (config.viewport.height - windowHeight) / 2,
|
||||
|
||||
child = ui.stack {
|
||||
children = [
|
||||
ui.rect { w = windowWidth, h = windowHeight, color = "#063351", radius = 0, strokeWidth = 1, strokeColor = "#1A5F80" },
|
||||
ui.padding {
|
||||
amount = dialogPadding,
|
||||
child = ui.column {
|
||||
gap = 0,
|
||||
children = [
|
||||
textInput {
|
||||
key = "palette-query",
|
||||
initialValue = paletteState.query,
|
||||
initialFocus = True,
|
||||
color = "white",
|
||||
backgroundColor = "rgba(0,0,0,0.2)",
|
||||
w = contentWidth,
|
||||
h = textInputHeight,
|
||||
onChange = text \ batch [paletteState.query := text],
|
||||
},
|
||||
child = ui.opacity {
|
||||
|
||||
scrollable {
|
||||
w = contentWidth,
|
||||
h = listHeight,
|
||||
totalHeight = totalHeight,
|
||||
totalWidth = contentWidth,
|
||||
scrollX = 0,
|
||||
scrollY = paletteState.scrollOffset,
|
||||
onScroll = onScroll,
|
||||
child = ui.column {
|
||||
gap = itemGap,
|
||||
children = [
|
||||
...(mapWithIndex (entry i \ entry
|
||||
| Section title \ box {
|
||||
w = contentWidth,
|
||||
h = sectionHeight,
|
||||
color = "transparent",
|
||||
paddingLeft = 6,
|
||||
paddingTop = 8,
|
||||
child = ui.text { content = title, color = "#bbb" },
|
||||
}
|
||||
| Item data \ paletteRow {
|
||||
child = data.label,
|
||||
w = contentWidth,
|
||||
h = textInputHeight,
|
||||
selected = (effectiveIndex == i),
|
||||
onClick = _ \ onSelect data.label
|
||||
}
|
||||
| _ \ empty
|
||||
) results)
|
||||
]
|
||||
opacity = paletteState.opacity,
|
||||
child = ui.stack {
|
||||
children = [
|
||||
ui.rect { w = windowWidth, h = windowHeight, color = "#063351", radius = 0, strokeWidth = 1, strokeColor = "#1A5F80" },
|
||||
ui.padding {
|
||||
amount = dialogPadding,
|
||||
child = ui.column {
|
||||
gap = 0,
|
||||
children = [
|
||||
textInput {
|
||||
key = "palette-query",
|
||||
initialValue = paletteState.query,
|
||||
initialFocus = True,
|
||||
color = "white",
|
||||
backgroundColor = "rgba(0,0,0,0.2)",
|
||||
w = contentWidth,
|
||||
h = textInputHeight,
|
||||
onChange = text \ batch [paletteState.query := text],
|
||||
},
|
||||
|
||||
scrollable {
|
||||
w = contentWidth,
|
||||
h = listHeight,
|
||||
totalHeight = totalHeight,
|
||||
totalWidth = contentWidth,
|
||||
scrollX = 0,
|
||||
scrollY = paletteState.scrollOffset,
|
||||
onScroll = onScroll,
|
||||
child = ui.column {
|
||||
gap = itemGap,
|
||||
children = [
|
||||
...(mapWithIndex (entry i \ entry
|
||||
| Section title \ box {
|
||||
w = contentWidth,
|
||||
h = sectionHeight,
|
||||
color = "transparent",
|
||||
paddingLeft = 6,
|
||||
paddingTop = 8,
|
||||
child = ui.text { content = title, color = "#bbb" },
|
||||
}
|
||||
| Item data \ paletteRow {
|
||||
child = data.label,
|
||||
w = contentWidth,
|
||||
h = textInputHeight,
|
||||
selected = (effectiveIndex == i),
|
||||
onClick = _ \ onSelect data.label
|
||||
}
|
||||
| _ \ empty
|
||||
) results)
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -6,6 +6,15 @@ inspector = config \
|
|||
sourceLines = split "\n" source;
|
||||
lineHeight = 20;
|
||||
|
||||
val = eval config.name;
|
||||
_ = debug "val" val;
|
||||
|
||||
reflected = val
|
||||
| Value v \ reflect v
|
||||
| _ \ reflect 0;
|
||||
|
||||
_ = debug "reflected" reflected;
|
||||
|
||||
dialogPadding = 0;
|
||||
|
||||
textInputHeight = 40;
|
||||
|
|
@ -20,25 +29,27 @@ inspector = config \
|
|||
w = config.w,
|
||||
h = config.h - textInputHeight,
|
||||
totalWidth = config.w,
|
||||
totalHeight = (len sourceLines) * lineHeight,
|
||||
# totalHeight = (len sourceLines) * lineHeight,
|
||||
totalHeight = 1000,
|
||||
onScroll = _ \ noOp,
|
||||
child = ui.column {
|
||||
gap = 0,
|
||||
children = map (line \
|
||||
ui.positioned {
|
||||
x = 8,
|
||||
y = 2,
|
||||
child = ui.text { content = line, color = "#ccc" }
|
||||
}
|
||||
) sourceLines
|
||||
}
|
||||
child = tree { value = reflected, depth = 0 },
|
||||
# child = ui.column {
|
||||
# gap = 0,
|
||||
# children = map (line \
|
||||
# ui.positioned {
|
||||
# x = 8,
|
||||
# y = 2,
|
||||
# child = ui.text { content = line, color = "#ccc" }
|
||||
# }
|
||||
# ) sourceLines
|
||||
# }
|
||||
},
|
||||
|
||||
# definition bar
|
||||
textInput {
|
||||
key = "inspector-redefine-" & config.name,
|
||||
color = "white",
|
||||
backgroundColor = "rgba(0,0,0,1)",
|
||||
backgroundColor = "rgba(255,255,255,0.2)",
|
||||
w = config.w,
|
||||
h = textInputHeight,
|
||||
onSubmit = text \ redefine config.name text
|
||||
|
|
|
|||
46
src/cg/06-tree.cg
Normal file
46
src/cg/06-tree.cg
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
tree = config \
|
||||
depth = config.depth;
|
||||
indent = depth * 20;
|
||||
|
||||
simple = content color \
|
||||
ui.positioned { x = indent, y = 0,
|
||||
child = ui.text { content = content, color = color }
|
||||
};
|
||||
|
||||
valueLabel = value \ value
|
||||
| NumberValue n \ Some (show n)
|
||||
| StringValue n \ Some ("\"" & n & "\"")
|
||||
| ConstructorValue { tag = tag } \ Some tag
|
||||
| FunctionValue _ \ Some "<fn>"
|
||||
| _ \ None;
|
||||
|
||||
config.value
|
||||
| NumberValue n \ simple (show n) "#6cf"
|
||||
| StringValue n \ simple ("\"" & n & "\"") "#f6a"
|
||||
| ConstructorValue { tag = tag } \ simple tag "#fc6"
|
||||
| FunctionValue _ \ simple "<fn>" "#888"
|
||||
| RecordValue entries \
|
||||
ui.column {
|
||||
gap = 0,
|
||||
children = map (entry \
|
||||
(valueLabel entry.value)
|
||||
| Some label \ simple (entry.key & " = " & label) "#aaa"
|
||||
| None \ ui.column { gap = 0, children = [
|
||||
simple entry.key "#aaa",
|
||||
tree { value = entry.value, depth = depth + 1 }
|
||||
]}
|
||||
) entries
|
||||
}
|
||||
| ListValue items \
|
||||
ui.column {
|
||||
gap = 0,
|
||||
children = mapWithIndex (item i \
|
||||
(valueLabel item)
|
||||
| Some label \ simple ((show i) & ": " & label) "#aaa"
|
||||
| None \ ui.column { gap = 0, children = [
|
||||
simple (show i) "#aaa",
|
||||
tree { value = item, depth = depth + 1 }
|
||||
]}
|
||||
) items
|
||||
}
|
||||
| _ \ ui.text { content = "?", color = "#666" };
|
||||
|
|
@ -129,6 +129,31 @@ export const _rt = {
|
|||
return { _tag: 'Ok' };
|
||||
},
|
||||
|
||||
reflect: (value: any): any => {
|
||||
if (value === null || value === undefined) return { _tag: 'NoneValue' };
|
||||
if (typeof value === 'number') return { _tag: 'NumberValue', _0: value };
|
||||
if (typeof value === 'string') return { _tag: 'StringValue', _0: value };
|
||||
if (Array.isArray(value)) return { _tag: 'ListValue', _0: value.map(_rt.reflect) };
|
||||
if (typeof value === 'function') {
|
||||
const source = value._astId !== undefined && astRegistry.get(value._astId)
|
||||
? prettyPrint(astRegistry.get(value._astId)!)
|
||||
: '<native>';
|
||||
return { _tag: 'FunctionValue', _0: source };
|
||||
}
|
||||
if (typeof value === 'object' && value._tag) {
|
||||
if ('_0' in value) return { _tag: 'ConstructorValue', _0: { tag: value._tag, value: _rt.reflect(value._0) } };
|
||||
return { _tag: 'ConstructorValue', _0: { tag: value._tag } };
|
||||
}
|
||||
if (typeof value === 'object') {
|
||||
const entries = Object.entries(value).map(([k, v]) => ({
|
||||
key: k,
|
||||
value: _rt.reflect(v)
|
||||
}));
|
||||
return { _tag: 'RecordValue', _0: entries };
|
||||
}
|
||||
return { _tag: 'NoneValue' };
|
||||
},
|
||||
|
||||
eval: (code: string) => {
|
||||
const trimmed = code.trim();
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue