String as a type
This commit is contained in:
@@ -83,8 +83,9 @@ atom:
|
||||
| VARIABLE # VariableExp
|
||||
| NUMBER # NumberExp
|
||||
| CONSTANT # ConstantExp
|
||||
| STRING # StringExp
|
||||
| LPAREN expr RPAREN # ParenExp
|
||||
| PIPE expr PIPE # AbsExp
|
||||
| PIPE expr PIPE # AbsExp
|
||||
| LBRACKET expr (COMMA expr)* RBRACKET # ListExp
|
||||
| VARIABLE LPAREN exprList? RPAREN # CallExp
|
||||
| NONE # NoneExp
|
||||
@@ -420,6 +421,9 @@ RBRACE: '}';
|
||||
|
||||
NUMBER: ([0-9]+ ('.' [0-9]*)? | '.' [0-9]+) ([eE][+-]? [0-9]+)?;
|
||||
CONSTANT: ('pi' | 'PI' | 'e' | 'E');
|
||||
STRING: '"' (~["\\\r\n] | '\\' .)* '"'
|
||||
| '\'' (~['\\\r\n] | '\\' .)* '\''
|
||||
;
|
||||
VARIABLE: [a-zA-Z_] [a-zA-Z_0-9]*;
|
||||
|
||||
SL_COMMENT: '#' ~[\r\n]* -> skip;
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -170,10 +170,11 @@ LBRACE=169
|
||||
RBRACE=170
|
||||
NUMBER=171
|
||||
CONSTANT=172
|
||||
VARIABLE=173
|
||||
SL_COMMENT=174
|
||||
ML_COMMENT=175
|
||||
WS=176
|
||||
STRING=173
|
||||
VARIABLE=174
|
||||
SL_COMMENT=175
|
||||
ML_COMMENT=176
|
||||
WS=177
|
||||
'sin'=1
|
||||
'cos'=2
|
||||
'tan'=3
|
||||
|
||||
File diff suppressed because one or more lines are too long
+725
-710
File diff suppressed because it is too large
Load Diff
@@ -170,10 +170,11 @@ LBRACE=169
|
||||
RBRACE=170
|
||||
NUMBER=171
|
||||
CONSTANT=172
|
||||
VARIABLE=173
|
||||
SL_COMMENT=174
|
||||
ML_COMMENT=175
|
||||
WS=176
|
||||
STRING=173
|
||||
VARIABLE=174
|
||||
SL_COMMENT=175
|
||||
ML_COMMENT=176
|
||||
WS=177
|
||||
'sin'=1
|
||||
'cos'=2
|
||||
'tan'=3
|
||||
|
||||
+1395
-1370
File diff suppressed because it is too large
Load Diff
@@ -294,6 +294,11 @@ class MathExprVisitor(ParseTreeVisitor):
|
||||
return self.visitChildren(ctx)
|
||||
|
||||
|
||||
# Visit a parse tree produced by MathExprParser#StringExp.
|
||||
def visitStringExp(self, ctx:MathExprParser.StringExpContext):
|
||||
return self.visitChildren(ctx)
|
||||
|
||||
|
||||
# Visit a parse tree produced by MathExprParser#ParenExp.
|
||||
def visitParenExp(self, ctx:MathExprParser.ParenExpContext):
|
||||
return self.visitChildren(ctx)
|
||||
|
||||
@@ -201,6 +201,11 @@ class UnifiedMathVisitor(MathExprVisitor):
|
||||
res.append((yield e))
|
||||
return res
|
||||
|
||||
def visitStringExp(self, ctx):
|
||||
val = yield ctx.VARIABLE().getText()
|
||||
|
||||
return val
|
||||
|
||||
def visitParenExp(self, ctx):
|
||||
return (yield ctx.expr())
|
||||
|
||||
@@ -668,7 +673,7 @@ class UnifiedMathVisitor(MathExprVisitor):
|
||||
val = (yield ctx.expr(0))
|
||||
min_v = (yield ctx.expr(1))
|
||||
max_v = (yield ctx.expr(2))
|
||||
|
||||
|
||||
if self._is_list(val):
|
||||
min_scalar = float(min_v.flatten()[0].item()) if self._is_tensor(min_v) else min_v
|
||||
max_scalar = float(max_v.flatten()[0].item()) if self._is_tensor(max_v) else max_v
|
||||
@@ -2604,7 +2609,7 @@ class UnifiedMathVisitor(MathExprVisitor):
|
||||
|
||||
if len(shape) == 0:
|
||||
return torch.tensor(0.0, device=self.device)
|
||||
|
||||
|
||||
offset_list = None
|
||||
if offset is not None:
|
||||
if self._is_tensor(offset):
|
||||
@@ -2676,7 +2681,7 @@ class UnifiedMathVisitor(MathExprVisitor):
|
||||
|
||||
if len(shape) == 0:
|
||||
return torch.tensor(0.0, device=self.device)
|
||||
|
||||
|
||||
offset_list = None
|
||||
if offset is not None:
|
||||
if self._is_tensor(offset):
|
||||
@@ -2734,7 +2739,7 @@ class UnifiedMathVisitor(MathExprVisitor):
|
||||
|
||||
if len(shape) == 0:
|
||||
return torch.tensor(0.0, device=self.device)
|
||||
|
||||
|
||||
offset_list = None
|
||||
if offset is not None:
|
||||
if self._is_tensor(offset):
|
||||
@@ -2752,7 +2757,7 @@ class UnifiedMathVisitor(MathExprVisitor):
|
||||
],
|
||||
indexing='ij'
|
||||
)
|
||||
|
||||
|
||||
# Call perlin_noise_nd with all coordinate grids
|
||||
noise = NoiseUtils.plasma_noise_nd(grids, scale, seed, self.device)
|
||||
|
||||
@@ -2793,7 +2798,7 @@ class UnifiedMathVisitor(MathExprVisitor):
|
||||
base = self._promote_to_tensor((yield ctx.expr(0)))
|
||||
overlay = self._promote_to_tensor((yield ctx.expr(1)))
|
||||
offset = yield ctx.expr(2)
|
||||
|
||||
|
||||
# Convert offset to list of ints
|
||||
if self._is_tensor(offset):
|
||||
offset = [int(x) for x in offset.flatten().tolist()]
|
||||
@@ -2801,38 +2806,38 @@ class UnifiedMathVisitor(MathExprVisitor):
|
||||
offset = [int(x) for x in offset]
|
||||
else:
|
||||
offset = [int(offset)]
|
||||
|
||||
|
||||
# Ensure offset matches base dimensions
|
||||
if len(offset) != base.ndim:
|
||||
raise ValueError(f"{ctx.start.line}:{ctx.start.column}: Offset dimensions {len(offset)} must match base dimensions {base.ndim}")
|
||||
|
||||
|
||||
# Calculate crop and paste regions
|
||||
crop_slices = []
|
||||
paste_slices = []
|
||||
|
||||
|
||||
for i in range(base.ndim):
|
||||
off = offset[i]
|
||||
overlay_size = overlay.shape[i]
|
||||
base_size = base.shape[i]
|
||||
|
||||
|
||||
# Determine overlay crop region (what part of overlay to use)
|
||||
crop_start = max(0, -off) # Crop from overlay if offset is negative
|
||||
crop_end = min(overlay_size, base_size - off) # Crop if overlay extends beyond base
|
||||
|
||||
|
||||
# Determine base paste region (where to place overlay in base)
|
||||
paste_start = max(0, off) # Start position in base
|
||||
paste_end = min(base_size, off + overlay_size) # End position in base
|
||||
|
||||
|
||||
crop_slices.append(slice(crop_start, crop_end))
|
||||
paste_slices.append(slice(paste_start, paste_end))
|
||||
|
||||
|
||||
# Crop overlay to fit
|
||||
cropped_overlay = overlay[tuple(crop_slices)]
|
||||
|
||||
|
||||
# Create result by cloning base and pasting overlay
|
||||
result = base.clone()
|
||||
result[tuple(paste_slices)] = cropped_overlay
|
||||
|
||||
|
||||
return result
|
||||
|
||||
|
||||
|
||||
+26
-23
@@ -56,17 +56,19 @@ function escapeHtml(value) {
|
||||
|
||||
function tokenize(text) {
|
||||
const tokens = [];
|
||||
const pattern = /#.*|\/\*[\s\S]*?\*\/|\b\d+(?:\.\d*)?(?:[eE][+-]?\d+)?\b|\B\.\d+(?:[eE][+-]?\d+)?\b|==|!=|>=|<=|<<|>>|->|[+\-*/%^=<>|?:,;()\[\]{}]|\b[a-zA-Z_][a-zA-Z_0-9]*\b|\s+|./g;
|
||||
const pattern = /#.*|\/\*[\s\S]*?\*\/|"(?:\\.|[^"\\\r\n])*"|'(?:\\.|[^'\\\r\n])*'|\b\d+(?:\.\d*)?(?:[eE][+-]?\d+)?\b|\B\.\d+(?:[eE][+-]?\d+)?\b|==|!=|>=|<=|<<|>>|->|[+\-*/%^=<>|?:,;()\[\]{}]|\b[a-zA-Z_][a-zA-Z_0-9]*\b|\s+|./g;
|
||||
let match;
|
||||
const bracketStack = [];
|
||||
|
||||
|
||||
while ((match = pattern.exec(text)) !== null) {
|
||||
const value = match[0];
|
||||
let type = "text";
|
||||
let depth = 0;
|
||||
|
||||
|
||||
if (value.startsWith("#") || value.startsWith("/*")) {
|
||||
type = "comment";
|
||||
} else if (value.startsWith('"') || value.startsWith("'")) {
|
||||
type = "string";
|
||||
} else if (OPENING_BRACKETS.has(value)) {
|
||||
depth = bracketStack.length;
|
||||
bracketStack.push(value);
|
||||
@@ -211,6 +213,7 @@ function ensureStyles() {
|
||||
.mrmth-token-function { color: #8e44ad; }
|
||||
.mrmth-token-variable { color: #ecf0f1; }
|
||||
.mrmth-token-operator { color: #95a5a6; }
|
||||
.mrmth-token-string { color: #4ea658; }
|
||||
.mrmth-token-bracket { font-weight: bold; }
|
||||
.mrmth-bracket-0 { color: #ffd700; }
|
||||
.mrmth-bracket-1 { color: #da70d6; }
|
||||
@@ -321,13 +324,13 @@ function attachLineNumbers(widget) {
|
||||
const updateNumbers = () => {
|
||||
const rawLines = inputEl.value.split("\n");
|
||||
const textLineCount = Math.max(1, rawLines.length);
|
||||
|
||||
|
||||
const gutterLines = [];
|
||||
|
||||
|
||||
// Sync syntaxLayer width to match inputEl's actual content width
|
||||
const scrollbarWidth = inputEl.offsetWidth - inputEl.clientWidth;
|
||||
syntaxLayer.style.width = `calc(100% - ${scrollbarWidth}px)`;
|
||||
|
||||
|
||||
// Create a temporary clone
|
||||
const measureClone = syntaxLayer.cloneNode(false);
|
||||
measureClone.style.position = "absolute";
|
||||
@@ -335,7 +338,7 @@ function attachLineNumbers(widget) {
|
||||
measureClone.style.width = syntaxLayer.style.width;
|
||||
measureClone.style.height = "auto";
|
||||
syntaxLayer.parentElement.appendChild(measureClone);
|
||||
|
||||
|
||||
// Build content with simple marker at start of each line
|
||||
let html = "";
|
||||
for (let i = 0; i < textLineCount; i++) {
|
||||
@@ -346,31 +349,31 @@ function attachLineNumbers(widget) {
|
||||
}
|
||||
}
|
||||
measureClone.innerHTML = html;
|
||||
|
||||
|
||||
// Simply read offsetTop of each marker
|
||||
const totalHeight = measureClone.offsetHeight;
|
||||
|
||||
|
||||
for (let i = 0; i < textLineCount; i++) {
|
||||
const marker = measureClone.querySelector(`[data-ln="${i}"]`);
|
||||
const nextMarker = i < textLineCount - 1 ? measureClone.querySelector(`[data-ln="${i + 1}"]`) : null;
|
||||
|
||||
|
||||
const currentY = marker ? marker.offsetTop : i * lineHeightPx;
|
||||
const nextY = nextMarker ? nextMarker.offsetTop : totalHeight;
|
||||
|
||||
|
||||
const heightDiff = nextY - currentY;
|
||||
const visualLines = Math.max(1, Math.round(heightDiff / lineHeightPx));
|
||||
|
||||
|
||||
gutterLines.push(String(i + 1));
|
||||
|
||||
|
||||
for (let j = 1; j < visualLines; j++) {
|
||||
gutterLines.push(" ");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
measureClone.remove();
|
||||
|
||||
|
||||
gutterContent.textContent = gutterLines.join("\n");
|
||||
|
||||
|
||||
gutter.style.height = `${inputEl.clientHeight}px`;
|
||||
gutterContent.style.transform = `translateY(${-inputEl.scrollTop}px)`;
|
||||
};
|
||||
@@ -391,30 +394,30 @@ function attachLineNumbers(widget) {
|
||||
|
||||
const selectionStart = inputEl.selectionStart;
|
||||
const selectionEnd = inputEl.selectionEnd;
|
||||
|
||||
|
||||
if (selectionStart !== selectionEnd) {
|
||||
return;
|
||||
}
|
||||
|
||||
const text = inputEl.value;
|
||||
const charAfter = text[selectionStart] || '';
|
||||
|
||||
|
||||
if (/[a-zA-Z0-9_]/.test(charAfter) || CLOSING_BRACKETS.has(charAfter)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const closingBracket = BRACKET_PAIRS[key];
|
||||
|
||||
|
||||
e.preventDefault();
|
||||
|
||||
|
||||
const before = text.substring(0, selectionStart);
|
||||
const after = text.substring(selectionStart);
|
||||
inputEl.value = before + key + closingBracket + after;
|
||||
inputEl.selectionStart = inputEl.selectionEnd = selectionStart + 1;
|
||||
|
||||
|
||||
updateNumbers();
|
||||
updateHighlight();
|
||||
|
||||
|
||||
const event = new Event('input', { bubbles: true });
|
||||
inputEl.dispatchEvent(event);
|
||||
};
|
||||
@@ -443,7 +446,7 @@ function attachLineNumbers(widget) {
|
||||
updateNumbers();
|
||||
updateHighlight();
|
||||
});
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user