BREAKING operator precedence change

This commit is contained in:
mcDandy
2026-10-13 08:47:59 +02:00
parent 35ba8ab32a
commit eb317bd2f5
12 changed files with 6339 additions and 6132 deletions
+21 -18
View File
@@ -8,7 +8,7 @@
* - A wide range of mathematical functions (trigonometric, hyperbolic, etc.)
* - Tensor operations (matmul, dot, reshape, etc.)
* - Noise functions (perlin, cellular, etc.)
* - Basic arithmetic, logical, and bitwise operations
* - Basic arithmetic, comparison, and bitwise function operations
*/
grammar MathExpr;
@@ -49,18 +49,21 @@ breakStmt: BREAK SEMICOLON;
continueStmt: CONTINUE SEMICOLON;
returnStmt: RETURN expr? SEMICOLON;
expr: ternaryExpr | atom | compExpr;
expr: ternaryExpr | compExpr;
ternaryExpr: compExpr QUESTION expr COLON expr # TernaryExp;
compExpr:
compExpr GT addExpr # GtExp
| compExpr GE addExpr # GeExp
| compExpr LT addExpr # LtExp
| compExpr LE addExpr # LeExp
| compExpr EQ addExpr # EqExp
| compExpr NE addExpr # NeExp
| addExpr # ToAdd;
compExpr EQ relationalExpr # EqExp
| compExpr NE relationalExpr # NeExp
| relationalExpr # ToRelational;
relationalExpr:
relationalExpr GT shiftExpr # GtExp
| relationalExpr GE shiftExpr # GeExp
| relationalExpr LT shiftExpr # LtExp
| relationalExpr LE shiftExpr # LeExp
| shiftExpr # ToShift;
addExpr:
addExpr PLUS mulExpr # AddExp
@@ -68,15 +71,15 @@ addExpr:
| mulExpr # ToMul;
mulExpr:
mulExpr MULT shiftExpr # MulExp
| mulExpr DIV shiftExpr # DivExp
| mulExpr MOD shiftExpr # ModExp
| shiftExpr # ToShift;
mulExpr MULT powExpr # MulExp
| mulExpr DIV powExpr # DivExp
| mulExpr MOD powExpr # ModExp
| powExpr # ToPow;
shiftExpr:
shiftExpr LSHIFT powExpr # LShiftExp
| shiftExpr RSHIFT powExpr # RShiftExp
| powExpr # ToPow;
shiftExpr LSHIFT addExpr # LShiftExp
| shiftExpr RSHIFT addExpr # RShiftExp
| addExpr # ToAdd;
powExpr: unaryExpr POW powExpr # PowExp | unaryExpr # ToUnary;
@@ -812,7 +815,7 @@ funcN:
/**
map(tensor, coord1, [coord2], [coord3]) - samples/remaps input tensor using coordinates
*/
| MAP LPAREN expr (COMMA expr)+ RPAREN # MapFunc
| MAP LPAREN expr COMMA expr (COMMA expr (COMMA expr)?)? RPAREN # MapFunc
/**
ezconvolution(tensor, [kernel_sizes...], kernel) - applies convolution with kernel. Attempts to correctly convolve over size dimensions.
*/
@@ -834,7 +837,7 @@ funcN:
*/
| UNSQUEEZE LPAREN expr COMMA expr RPAREN # UnsqueezeFunc
/**
concatenate(x1, x2, ..., dim) - concatenates tensors along the specified dimension
concatenate(x, ..., dim) - concatenates one or more tensors along the specified dimension
*/
| CONCAT LPAREN expr (COMMA expr)+ RPAREN # ConcatFunc
/**
+18 -15
View File
@@ -846,17 +846,17 @@ class UnifiedMathVisitor(MathExprVisitor):
def visitMulExp(self, ctx):
a = yield ctx.mulExpr()
b = yield ctx.shiftExpr()
b = yield ctx.powExpr()
return self._bin_op(a, b, torch.mul, lambda a, b: a * b, ctx)
def visitDivExp(self, ctx):
a = yield ctx.mulExpr()
b = yield ctx.shiftExpr()
b = yield ctx.powExpr()
return self._bin_op(a, b, torch.div, lambda a, b: a / b, ctx)
def visitModExp(self, ctx):
a = yield ctx.mulExpr()
b = yield ctx.shiftExpr()
b = yield ctx.powExpr()
return self._bin_op(a, b, torch.remainder, lambda a, b: a % b, ctx)
def visitPowExp(self, ctx):
@@ -875,34 +875,37 @@ class UnifiedMathVisitor(MathExprVisitor):
def visitNeExp(self, ctx):
a = yield ctx.compExpr()
b = yield ctx.addExpr()
b = yield ctx.relationalExpr()
return self._bool_op(a, b, torch.ne, lambda a, b: a != b, ctx)
def visitEqExp(self, ctx):
a = yield ctx.compExpr()
b = yield ctx.addExpr()
b = yield ctx.relationalExpr()
return self._bool_op(a, b, torch.eq, lambda a, b: a == b, ctx)
def visitGtExp(self, ctx):
a = yield ctx.compExpr()
b = yield ctx.addExpr()
a = yield ctx.relationalExpr()
b = yield ctx.shiftExpr()
return self._bool_op(a, b, torch.gt, lambda a, b: a > b, ctx)
def visitLtExp(self, ctx):
a = yield ctx.compExpr()
b = yield ctx.addExpr()
a = yield ctx.relationalExpr()
b = yield ctx.shiftExpr()
return self._bool_op(a, b, torch.lt, lambda a, b: a < b, ctx)
def visitGeExp(self, ctx):
a = yield ctx.compExpr()
b = yield ctx.addExpr()
a = yield ctx.relationalExpr()
b = yield ctx.shiftExpr()
return self._bool_op(a, b, torch.ge, lambda a, b: a >= b, ctx)
def visitLeExp(self, ctx):
a = yield ctx.compExpr()
b = yield ctx.addExpr()
a = yield ctx.relationalExpr()
b = yield ctx.shiftExpr()
return self._bool_op(a, b, torch.le, lambda a, b: a <= b, ctx)
def visitToRelational(self, ctx):
return (yield ctx.relationalExpr())
def visitToAdd(self, ctx):
return (yield ctx.addExpr())
@@ -3750,12 +3753,12 @@ class UnifiedMathVisitor(MathExprVisitor):
def visitLShiftExp(self, ctx):
a = yield ctx.shiftExpr()
b = yield ctx.powExpr()
b = yield ctx.addExpr()
return self._bitwise_op(a, b, torch.bitwise_left_shift, self._scalar_bitwise_lshift,ctx)
def visitRShiftExp(self, ctx):
a = yield ctx.shiftExpr()
b = yield ctx.powExpr()
b = yield ctx.addExpr()
return self._bitwise_op(a, b, torch.bitwise_right_shift, self._scalar_bitwise_rshift,ctx)
def visitBitAndFunc(self, ctx):
File diff suppressed because one or more lines are too long
+44 -35
View File
@@ -224,12 +224,12 @@ class MathExprListener(ParseTreeListener):
pass
# Enter a parse tree produced by MathExprParser#LtExp.
def enterLtExp(self, ctx:MathExprParser.LtExpContext):
# Enter a parse tree produced by MathExprParser#ToRelational.
def enterToRelational(self, ctx:MathExprParser.ToRelationalContext):
pass
# Exit a parse tree produced by MathExprParser#LtExp.
def exitLtExp(self, ctx:MathExprParser.LtExpContext):
# Exit a parse tree produced by MathExprParser#ToRelational.
def exitToRelational(self, ctx:MathExprParser.ToRelationalContext):
pass
@@ -242,12 +242,30 @@ class MathExprListener(ParseTreeListener):
pass
# Enter a parse tree produced by MathExprParser#ToAdd.
def enterToAdd(self, ctx:MathExprParser.ToAddContext):
# Enter a parse tree produced by MathExprParser#NeExp.
def enterNeExp(self, ctx:MathExprParser.NeExpContext):
pass
# Exit a parse tree produced by MathExprParser#ToAdd.
def exitToAdd(self, ctx:MathExprParser.ToAddContext):
# Exit a parse tree produced by MathExprParser#NeExp.
def exitNeExp(self, ctx:MathExprParser.NeExpContext):
pass
# Enter a parse tree produced by MathExprParser#ToShift.
def enterToShift(self, ctx:MathExprParser.ToShiftContext):
pass
# Exit a parse tree produced by MathExprParser#ToShift.
def exitToShift(self, ctx:MathExprParser.ToShiftContext):
pass
# Enter a parse tree produced by MathExprParser#LtExp.
def enterLtExp(self, ctx:MathExprParser.LtExpContext):
pass
# Exit a parse tree produced by MathExprParser#LtExp.
def exitLtExp(self, ctx:MathExprParser.LtExpContext):
pass
@@ -269,15 +287,6 @@ class MathExprListener(ParseTreeListener):
pass
# Enter a parse tree produced by MathExprParser#NeExp.
def enterNeExp(self, ctx:MathExprParser.NeExpContext):
pass
# Exit a parse tree produced by MathExprParser#NeExp.
def exitNeExp(self, ctx:MathExprParser.NeExpContext):
pass
# Enter a parse tree produced by MathExprParser#GtExp.
def enterGtExp(self, ctx:MathExprParser.GtExpContext):
pass
@@ -314,15 +323,6 @@ class MathExprListener(ParseTreeListener):
pass
# Enter a parse tree produced by MathExprParser#ToShift.
def enterToShift(self, ctx:MathExprParser.ToShiftContext):
pass
# Exit a parse tree produced by MathExprParser#ToShift.
def exitToShift(self, ctx:MathExprParser.ToShiftContext):
pass
# Enter a parse tree produced by MathExprParser#MulExp.
def enterMulExp(self, ctx:MathExprParser.MulExpContext):
pass
@@ -350,6 +350,24 @@ class MathExprListener(ParseTreeListener):
pass
# Enter a parse tree produced by MathExprParser#ToPow.
def enterToPow(self, ctx:MathExprParser.ToPowContext):
pass
# Exit a parse tree produced by MathExprParser#ToPow.
def exitToPow(self, ctx:MathExprParser.ToPowContext):
pass
# Enter a parse tree produced by MathExprParser#ToAdd.
def enterToAdd(self, ctx:MathExprParser.ToAddContext):
pass
# Exit a parse tree produced by MathExprParser#ToAdd.
def exitToAdd(self, ctx:MathExprParser.ToAddContext):
pass
# Enter a parse tree produced by MathExprParser#RShiftExp.
def enterRShiftExp(self, ctx:MathExprParser.RShiftExpContext):
pass
@@ -368,15 +386,6 @@ class MathExprListener(ParseTreeListener):
pass
# Enter a parse tree produced by MathExprParser#ToPow.
def enterToPow(self, ctx:MathExprParser.ToPowContext):
pass
# Exit a parse tree produced by MathExprParser#ToPow.
def exitToPow(self, ctx:MathExprParser.ToPowContext):
pass
# Enter a parse tree produced by MathExprParser#PowExp.
def enterPowExp(self, ctx:MathExprParser.PowExpContext):
pass
File diff suppressed because it is too large Load Diff
+24 -19
View File
@@ -129,8 +129,8 @@ class MathExprVisitor(ParseTreeVisitor):
return self.visitChildren(ctx)
# Visit a parse tree produced by MathExprParser#LtExp.
def visitLtExp(self, ctx:MathExprParser.LtExpContext):
# Visit a parse tree produced by MathExprParser#ToRelational.
def visitToRelational(self, ctx:MathExprParser.ToRelationalContext):
return self.visitChildren(ctx)
@@ -139,8 +139,18 @@ class MathExprVisitor(ParseTreeVisitor):
return self.visitChildren(ctx)
# Visit a parse tree produced by MathExprParser#ToAdd.
def visitToAdd(self, ctx:MathExprParser.ToAddContext):
# Visit a parse tree produced by MathExprParser#NeExp.
def visitNeExp(self, ctx:MathExprParser.NeExpContext):
return self.visitChildren(ctx)
# Visit a parse tree produced by MathExprParser#ToShift.
def visitToShift(self, ctx:MathExprParser.ToShiftContext):
return self.visitChildren(ctx)
# Visit a parse tree produced by MathExprParser#LtExp.
def visitLtExp(self, ctx:MathExprParser.LtExpContext):
return self.visitChildren(ctx)
@@ -154,11 +164,6 @@ class MathExprVisitor(ParseTreeVisitor):
return self.visitChildren(ctx)
# Visit a parse tree produced by MathExprParser#NeExp.
def visitNeExp(self, ctx:MathExprParser.NeExpContext):
return self.visitChildren(ctx)
# Visit a parse tree produced by MathExprParser#GtExp.
def visitGtExp(self, ctx:MathExprParser.GtExpContext):
return self.visitChildren(ctx)
@@ -179,11 +184,6 @@ class MathExprVisitor(ParseTreeVisitor):
return self.visitChildren(ctx)
# Visit a parse tree produced by MathExprParser#ToShift.
def visitToShift(self, ctx:MathExprParser.ToShiftContext):
return self.visitChildren(ctx)
# Visit a parse tree produced by MathExprParser#MulExp.
def visitMulExp(self, ctx:MathExprParser.MulExpContext):
return self.visitChildren(ctx)
@@ -199,6 +199,16 @@ class MathExprVisitor(ParseTreeVisitor):
return self.visitChildren(ctx)
# Visit a parse tree produced by MathExprParser#ToPow.
def visitToPow(self, ctx:MathExprParser.ToPowContext):
return self.visitChildren(ctx)
# Visit a parse tree produced by MathExprParser#ToAdd.
def visitToAdd(self, ctx:MathExprParser.ToAddContext):
return self.visitChildren(ctx)
# Visit a parse tree produced by MathExprParser#RShiftExp.
def visitRShiftExp(self, ctx:MathExprParser.RShiftExpContext):
return self.visitChildren(ctx)
@@ -209,11 +219,6 @@ class MathExprVisitor(ParseTreeVisitor):
return self.visitChildren(ctx)
# Visit a parse tree produced by MathExprParser#ToPow.
def visitToPow(self, ctx:MathExprParser.ToPowContext):
return self.visitChildren(ctx)
# Visit a parse tree produced by MathExprParser#PowExp.
def visitPowExp(self, ctx:MathExprParser.PowExpContext):
return self.visitChildren(ctx)
+3 -3
View File
@@ -172,9 +172,9 @@ INBUILT_FUNCTION_META = {
'stack_clear': {'min_args': 1, 'max_args': 1, 'snippet': 'stack_clear(slot)', 'description': 'clears the contents of slot stack'},
'stack_has': {'min_args': 1, 'max_args': 1, 'snippet': 'stack_has(slot)', 'description': 'returns 1.0 if slot exists in stack and is not empty else returns 0.0'},
'stack_get': {'min_args': 1, 'max_args': 1, 'snippet': 'stack_get(slot)', 'description': 'returns the last pushed value in slot without popping it'},
'cat': {'min_args': 3, 'max_args': None, 'snippet': 'cat(x1, x2, ..., dim)', 'description': 'concatenates tensors along the specified dimension'},
'concat': {'min_args': 3, 'max_args': None, 'snippet': 'concat(x1, x2, ..., dim)', 'description': 'concatenates tensors along the specified dimension'},
'concatenate': {'min_args': 3, 'max_args': None, 'snippet': 'concatenate(x1, x2, ..., dim)', 'description': 'concatenates tensors along the specified dimension'},
'cat': {'min_args': 2, 'max_args': None, 'snippet': 'cat(x, ..., dim)', 'description': 'concatenates one or more tensors along the specified dimension'},
'concat': {'min_args': 2, 'max_args': None, 'snippet': 'concat(x, ..., dim)', 'description': 'concatenates one or more tensors along the specified dimension'},
'concatenate': {'min_args': 2, 'max_args': None, 'snippet': 'concatenate(x, ..., dim)', 'description': 'concatenates one or more tensors along the specified dimension'},
'int': {'min_args': 1, 'max_args': 1, 'snippet': 'int(x)', 'description': 'casts x to integer'},
'float': {'min_args': 1, 'max_args': 1, 'snippet': 'float(x)', 'description': 'casts x to float'},
'upper': {'min_args': 1, 'max_args': 1, 'snippet': 'upper(x)', 'description': 'converts string to uppercase'},
File diff suppressed because one or more lines are too long
+44 -35
View File
@@ -224,12 +224,12 @@ class MathExprListener(ParseTreeListener):
pass
# Enter a parse tree produced by MathExprParser#LtExp.
def enterLtExp(self, ctx:MathExprParser.LtExpContext):
# Enter a parse tree produced by MathExprParser#ToRelational.
def enterToRelational(self, ctx:MathExprParser.ToRelationalContext):
pass
# Exit a parse tree produced by MathExprParser#LtExp.
def exitLtExp(self, ctx:MathExprParser.LtExpContext):
# Exit a parse tree produced by MathExprParser#ToRelational.
def exitToRelational(self, ctx:MathExprParser.ToRelationalContext):
pass
@@ -242,12 +242,30 @@ class MathExprListener(ParseTreeListener):
pass
# Enter a parse tree produced by MathExprParser#ToAdd.
def enterToAdd(self, ctx:MathExprParser.ToAddContext):
# Enter a parse tree produced by MathExprParser#NeExp.
def enterNeExp(self, ctx:MathExprParser.NeExpContext):
pass
# Exit a parse tree produced by MathExprParser#ToAdd.
def exitToAdd(self, ctx:MathExprParser.ToAddContext):
# Exit a parse tree produced by MathExprParser#NeExp.
def exitNeExp(self, ctx:MathExprParser.NeExpContext):
pass
# Enter a parse tree produced by MathExprParser#ToShift.
def enterToShift(self, ctx:MathExprParser.ToShiftContext):
pass
# Exit a parse tree produced by MathExprParser#ToShift.
def exitToShift(self, ctx:MathExprParser.ToShiftContext):
pass
# Enter a parse tree produced by MathExprParser#LtExp.
def enterLtExp(self, ctx:MathExprParser.LtExpContext):
pass
# Exit a parse tree produced by MathExprParser#LtExp.
def exitLtExp(self, ctx:MathExprParser.LtExpContext):
pass
@@ -269,15 +287,6 @@ class MathExprListener(ParseTreeListener):
pass
# Enter a parse tree produced by MathExprParser#NeExp.
def enterNeExp(self, ctx:MathExprParser.NeExpContext):
pass
# Exit a parse tree produced by MathExprParser#NeExp.
def exitNeExp(self, ctx:MathExprParser.NeExpContext):
pass
# Enter a parse tree produced by MathExprParser#GtExp.
def enterGtExp(self, ctx:MathExprParser.GtExpContext):
pass
@@ -314,15 +323,6 @@ class MathExprListener(ParseTreeListener):
pass
# Enter a parse tree produced by MathExprParser#ToShift.
def enterToShift(self, ctx:MathExprParser.ToShiftContext):
pass
# Exit a parse tree produced by MathExprParser#ToShift.
def exitToShift(self, ctx:MathExprParser.ToShiftContext):
pass
# Enter a parse tree produced by MathExprParser#MulExp.
def enterMulExp(self, ctx:MathExprParser.MulExpContext):
pass
@@ -350,6 +350,24 @@ class MathExprListener(ParseTreeListener):
pass
# Enter a parse tree produced by MathExprParser#ToPow.
def enterToPow(self, ctx:MathExprParser.ToPowContext):
pass
# Exit a parse tree produced by MathExprParser#ToPow.
def exitToPow(self, ctx:MathExprParser.ToPowContext):
pass
# Enter a parse tree produced by MathExprParser#ToAdd.
def enterToAdd(self, ctx:MathExprParser.ToAddContext):
pass
# Exit a parse tree produced by MathExprParser#ToAdd.
def exitToAdd(self, ctx:MathExprParser.ToAddContext):
pass
# Enter a parse tree produced by MathExprParser#RShiftExp.
def enterRShiftExp(self, ctx:MathExprParser.RShiftExpContext):
pass
@@ -368,15 +386,6 @@ class MathExprListener(ParseTreeListener):
pass
# Enter a parse tree produced by MathExprParser#ToPow.
def enterToPow(self, ctx:MathExprParser.ToPowContext):
pass
# Exit a parse tree produced by MathExprParser#ToPow.
def exitToPow(self, ctx:MathExprParser.ToPowContext):
pass
# Enter a parse tree produced by MathExprParser#PowExp.
def enterPowExp(self, ctx:MathExprParser.PowExpContext):
pass
File diff suppressed because one or more lines are too long
+24 -19
View File
@@ -129,8 +129,8 @@ class MathExprVisitor(ParseTreeVisitor):
return self.visitChildren(ctx)
# Visit a parse tree produced by MathExprParser#LtExp.
def visitLtExp(self, ctx:MathExprParser.LtExpContext):
# Visit a parse tree produced by MathExprParser#ToRelational.
def visitToRelational(self, ctx:MathExprParser.ToRelationalContext):
return self.visitChildren(ctx)
@@ -139,8 +139,18 @@ class MathExprVisitor(ParseTreeVisitor):
return self.visitChildren(ctx)
# Visit a parse tree produced by MathExprParser#ToAdd.
def visitToAdd(self, ctx:MathExprParser.ToAddContext):
# Visit a parse tree produced by MathExprParser#NeExp.
def visitNeExp(self, ctx:MathExprParser.NeExpContext):
return self.visitChildren(ctx)
# Visit a parse tree produced by MathExprParser#ToShift.
def visitToShift(self, ctx:MathExprParser.ToShiftContext):
return self.visitChildren(ctx)
# Visit a parse tree produced by MathExprParser#LtExp.
def visitLtExp(self, ctx:MathExprParser.LtExpContext):
return self.visitChildren(ctx)
@@ -154,11 +164,6 @@ class MathExprVisitor(ParseTreeVisitor):
return self.visitChildren(ctx)
# Visit a parse tree produced by MathExprParser#NeExp.
def visitNeExp(self, ctx:MathExprParser.NeExpContext):
return self.visitChildren(ctx)
# Visit a parse tree produced by MathExprParser#GtExp.
def visitGtExp(self, ctx:MathExprParser.GtExpContext):
return self.visitChildren(ctx)
@@ -179,11 +184,6 @@ class MathExprVisitor(ParseTreeVisitor):
return self.visitChildren(ctx)
# Visit a parse tree produced by MathExprParser#ToShift.
def visitToShift(self, ctx:MathExprParser.ToShiftContext):
return self.visitChildren(ctx)
# Visit a parse tree produced by MathExprParser#MulExp.
def visitMulExp(self, ctx:MathExprParser.MulExpContext):
return self.visitChildren(ctx)
@@ -199,6 +199,16 @@ class MathExprVisitor(ParseTreeVisitor):
return self.visitChildren(ctx)
# Visit a parse tree produced by MathExprParser#ToPow.
def visitToPow(self, ctx:MathExprParser.ToPowContext):
return self.visitChildren(ctx)
# Visit a parse tree produced by MathExprParser#ToAdd.
def visitToAdd(self, ctx:MathExprParser.ToAddContext):
return self.visitChildren(ctx)
# Visit a parse tree produced by MathExprParser#RShiftExp.
def visitRShiftExp(self, ctx:MathExprParser.RShiftExpContext):
return self.visitChildren(ctx)
@@ -209,11 +219,6 @@ class MathExprVisitor(ParseTreeVisitor):
return self.visitChildren(ctx)
# Visit a parse tree produced by MathExprParser#ToPow.
def visitToPow(self, ctx:MathExprParser.ToPowContext):
return self.visitChildren(ctx)
# Visit a parse tree produced by MathExprParser#PowExp.
def visitPowExp(self, ctx:MathExprParser.PowExpContext):
return self.visitChildren(ctx)
+3 -3
View File
@@ -175,9 +175,9 @@ export const FUNCTION_META = {
"stack_clear": { minArgs: 1, maxArgs: 1, snippet: "stack_clear(slot)", description: "clears the contents of slot stack" },
"stack_has": { minArgs: 1, maxArgs: 1, snippet: "stack_has(slot)", description: "returns 1.0 if slot exists in stack and is not empty else returns 0.0" },
"stack_get": { minArgs: 1, maxArgs: 1, snippet: "stack_get(slot)", description: "returns the last pushed value in slot without popping it" },
"cat": { minArgs: 3, maxArgs: null, snippet: "cat(x1, x2, ..., dim)", description: "concatenates tensors along the specified dimension" },
"concat": { minArgs: 3, maxArgs: null, snippet: "concat(x1, x2, ..., dim)", description: "concatenates tensors along the specified dimension" },
"concatenate": { minArgs: 3, maxArgs: null, snippet: "concatenate(x1, x2, ..., dim)", description: "concatenates tensors along the specified dimension" },
"cat": { minArgs: 2, maxArgs: null, snippet: "cat(x, ..., dim)", description: "concatenates one or more tensors along the specified dimension" },
"concat": { minArgs: 2, maxArgs: null, snippet: "concat(x, ..., dim)", description: "concatenates one or more tensors along the specified dimension" },
"concatenate": { minArgs: 2, maxArgs: null, snippet: "concatenate(x, ..., dim)", description: "concatenates one or more tensors along the specified dimension" },
"int": { minArgs: 1, maxArgs: 1, snippet: "int(x)", description: "casts x to integer" },
"float": { minArgs: 1, maxArgs: 1, snippet: "float(x)", description: "casts x to float" },
"upper": { minArgs: 1, maxArgs: 1, snippet: "upper(x)", description: "converts string to uppercase" },