diff --git a/example/testing.jv b/example/testing.jv new file mode 100644 index 00000000..9e4ec089 --- /dev/null +++ b/example/testing.jv @@ -0,0 +1,69 @@ +pipeline CarsPipeline { + + CarsExtractor + -> CarsTextFileInterpreter + -> CarsCSVInterpreter + -> NameHeaderWriter + -> CarsTableInterpreter + -> MyTableTransformer + -> CarsLoader; + + + block CarsExtractor oftype HttpExtractor { + url: "https://gist.githubusercontent.com/noamross/e5d3e859aa0c794be10b/raw/b999fb4425b54c63cab088c0ce2c0d6ce961a563/cars.csv"; + } + + + block CarsTextFileInterpreter oftype TextFileInterpreter { } + + block CarsCSVInterpreter oftype CSVInterpreter { + enclosing: '"'; + } + + block NameHeaderWriter oftype CellWriter { + at: cell A1; + + write: [ + "name" + ]; + } + + block CarsTableInterpreter oftype TableInterpreter { + header: true; + columns: [ + "name" oftype text, + "mpg" oftype decimal, + "cyl" oftype integer, + "disp" oftype decimal, + "hp" oftype integer, + "drat" oftype decimal, + "wt" oftype decimal, + "qsec" oftype decimal, + "vs" oftype integer, + "am" oftype integer, + "gear" oftype integer, + "carb" oftype integer + ]; + } + + transform IdentityTransform { + from mpg oftype decimal; + from cyl oftype integer; + to o oftype decimal; + + o: mpg + cyl; + } + + block MyTableTransformer oftype TableTransformer { + inputColumns: ['mpg', 'cyl']; + outputColumn: 'f(mpg, cyl)'; + + use: IdentityTransform; + } + + block CarsLoader oftype SQLiteLoader { + table: "Cars"; + file: "./cars.sqlite"; + } +} + diff --git a/libs/execution/src/lib/transforms/transform-executor.ts b/libs/execution/src/lib/transforms/transform-executor.ts index bf02ec8c..ff430692 100644 --- a/libs/execution/src/lib/transforms/transform-executor.ts +++ b/libs/execution/src/lib/transforms/transform-executor.ts @@ -7,7 +7,6 @@ import { strict as assert } from 'assert'; import { type EvaluationContext, - INTERNAL_VALUE_REPRESENTATION_TYPEGUARD, type InternalValueRepresentation, type PolarsInternal, type TransformDefinition, @@ -89,7 +88,7 @@ export abstract class TransformExecutor { export class PolarsTransformExecutor extends TransformExecutor< string[], - InternalValueRepresentation | PolarsInternal + PolarsInternal > { private static addInputColumnsToContext( inputDetailsList: readonly PortDetails[], @@ -107,7 +106,7 @@ export class PolarsTransformExecutor extends TransformExecutor< protected override doExecuteTransform( inputColumns: string[], context: ExecutionContext, - ): InternalValueRepresentation | PolarsInternal | undefined { + ): PolarsInternal | undefined { const inputDetails = this.getInputDetails(); const outputDetails = this.getOutputDetails(); @@ -117,10 +116,9 @@ export class PolarsTransformExecutor extends TransformExecutor< context.evaluationContext, ); - let newValue: InternalValueRepresentation | PolarsInternal | undefined = - undefined; + let expr: PolarsInternal | undefined = undefined; try { - newValue = polarsEvaluateExpression( + expr = polarsEvaluateExpression( this.getOutputAssignment().expression, context.evaluationContext, context.wrapperFactories, @@ -133,30 +131,15 @@ export class PolarsTransformExecutor extends TransformExecutor< } } - if (newValue === undefined) { + if (expr === undefined) { return undefined; } - if (INTERNAL_VALUE_REPRESENTATION_TYPEGUARD(newValue)) { - if ( - !isValidValueRepresentation(newValue, outputDetails.valueType, context) - ) { - context.logger.logDebug( - `Invalid value: "${JSON.stringify( - newValue, - )}" does not match the type ${outputDetails.valueType.getName()}`, - ); - return undefined; - } - return newValue; - } - - // typeof newValue === PolarsInternal const otype = outputDetails.valueType.toPolarsDataType(); if (otype === undefined) { return undefined; } - return newValue.cast(otype); + return expr.cast(otype); } } @@ -257,7 +240,6 @@ export class TsTransformExecutor extends TransformExecutor< private addVariablesToContext( inputDetailsList: PortDetails[], - columns: ReadonlyMap, rowIndex: number, context: ExecutionContext, diff --git a/libs/extensions/tabular/exec/src/lib/table-transformer-executor.ts b/libs/extensions/tabular/exec/src/lib/table-transformer-executor.ts index 0107e9b7..cdff06fb 100644 --- a/libs/extensions/tabular/exec/src/lib/table-transformer-executor.ts +++ b/libs/extensions/tabular/exec/src/lib/table-transformer-executor.ts @@ -14,13 +14,7 @@ import { TsTransformExecutor, implementsStatic, } from '@jvalue/jayvee-execution'; -import { - INTERNAL_VALUE_REPRESENTATION_TYPEGUARD, - IOType, - type InternalValueRepresentation, - type PolarsInternal, -} from '@jvalue/jayvee-language-server'; -import { pl } from 'nodejs-polars'; +import { IOType } from '@jvalue/jayvee-language-server'; export abstract class TableTransformerExecutor extends AbstractBlockExecutor< IOType.TABLE, @@ -119,16 +113,6 @@ export abstract class TableTransformerExecutor extends AbstractBlockExecutor< export class PolarsTableTransformerExecutor extends TableTransformerExecutor { public static readonly type = 'PolarsTableTransformer'; - private newColumn( - x: InternalValueRepresentation | PolarsInternal, - nrows: number, - ): PolarsInternal | pl.Series { - if (INTERNAL_VALUE_REPRESENTATION_TYPEGUARD(x)) { - return pl.repeat(x, nrows); - } - return x; - } - // eslint-disable-next-line @typescript-eslint/require-await override async doExecute( inputTable: R.PolarsTable, @@ -172,7 +156,7 @@ export class PolarsTableTransformerExecutor extends TableTransformerExecutor { return checkInputColumnsMatchTransformInputTypesResult; } - const newValue = executor.executeTransform(inputColumnNames, context); + const expr = executor.executeTransform(inputColumnNames, context); this.logColumnOverwriteStatus( inputTable, @@ -181,7 +165,7 @@ export class PolarsTableTransformerExecutor extends TableTransformerExecutor { executor.getOutputDetails(), ); - if (newValue === undefined) { + if (expr === undefined) { return R.err({ message: 'Skipping transform: Could not evaluate transform expression', diagnostic: { @@ -190,8 +174,7 @@ export class PolarsTableTransformerExecutor extends TableTransformerExecutor { }); } - const ncol = this.newColumn(newValue, inputTable.getNumberOfRows()); - const ndf = inputTable.df.withColumn(ncol.alias(outputColumnName)); + const ndf = inputTable.df.withColumn(expr.alias(outputColumnName)); return R.ok(new R.PolarsTable(ndf)); } } diff --git a/libs/language-server/src/lib/ast/expressions/evaluate-expression.ts b/libs/language-server/src/lib/ast/expressions/evaluate-expression.ts index a34d9313..0810b8c5 100644 --- a/libs/language-server/src/lib/ast/expressions/evaluate-expression.ts +++ b/libs/language-server/src/lib/ast/expressions/evaluate-expression.ts @@ -6,6 +6,7 @@ import { strict as assert } from 'assert'; import { assertUnreachable } from 'langium'; +import { pl } from 'nodejs-polars'; import { type ValidationContext } from '../../validation'; import { @@ -37,8 +38,8 @@ import { type PolarsInternal, } from './internal-value-representation'; import { - PolarsOperatorEvaluator, type OperatorEvaluator, + type PolarsOperatorEvaluator, } from './operator-evaluator'; import { INTERNAL_VALUE_REPRESENTATION_TYPEGUARD, @@ -111,7 +112,7 @@ function getEvaluator( if (isTernaryExpression(expression)) { const operator = expression.operator; throw new Error('Ternary operations are not supported yet'); - //return evaluationContext.operatorRegistry.ternary[operator]; + // return evaluationContext.operatorRegistry.ternary[operator]; } assertUnreachable(expression); } @@ -122,21 +123,29 @@ export function polarsEvaluateExpression( wrapperFactories: WrapperFactoryProvider, context: ValidationContext | undefined = undefined, strategy: EvaluationStrategy = EvaluationStrategy.LAZY, -): InternalValueRepresentation | PolarsInternal | undefined { +): PolarsInternal | undefined { if (expression === undefined) { return undefined; } if (isExpressionLiteral(expression)) { if (isFreeVariableLiteral(expression)) { - return evaluationContext.getValueFor(expression); + const fv = evaluationContext.getValueFor(expression); + if (INTERNAL_VALUE_REPRESENTATION_TYPEGUARD(fv)) { + return pl.lit(fv); + } + return fv; } else if (isValueLiteral(expression)) { - return evaluateValueLiteral( + const lit = evaluateValueLiteral( expression, evaluationContext, wrapperFactories, context, strategy, ); + if (lit === undefined) { + return undefined; + } + return pl.lit(lit); } assertUnreachable(expression); } diff --git a/libs/language-server/src/lib/ast/expressions/evaluators/addition-operator-evaluator.ts b/libs/language-server/src/lib/ast/expressions/evaluators/addition-operator-evaluator.ts index e82f7906..d1d451b6 100644 --- a/libs/language-server/src/lib/ast/expressions/evaluators/addition-operator-evaluator.ts +++ b/libs/language-server/src/lib/ast/expressions/evaluators/addition-operator-evaluator.ts @@ -18,14 +18,9 @@ export class AdditionOperatorEvaluator extends DefaultBinaryOperatorEvaluator< return leftValue + rightValue; } override polarsDoEvaluate( - left: number | PolarsInternal, - right: number | PolarsInternal, - ): number | PolarsInternal { - if (NUMBER_TYPEGUARD(left)) { - return NUMBER_TYPEGUARD(right) - ? this.doEvaluate(left, right) - : right.plus(left); - } + left: PolarsInternal, + right: PolarsInternal, + ): PolarsInternal { return left.plus(right); } } diff --git a/libs/language-server/src/lib/ast/expressions/evaluators/and-operator-evaluator.ts b/libs/language-server/src/lib/ast/expressions/evaluators/and-operator-evaluator.ts index 5787d6dc..7453871c 100644 --- a/libs/language-server/src/lib/ast/expressions/evaluators/and-operator-evaluator.ts +++ b/libs/language-server/src/lib/ast/expressions/evaluators/and-operator-evaluator.ts @@ -4,7 +4,6 @@ import { type PolarsInternal } from '../internal-value-representation'; import { BooleanShortCircuitOperatorEvaluator } from '../operator-evaluator'; -import { BOOLEAN_TYPEGUARD } from '../typeguards'; export class AndOperatorEvaluator extends BooleanShortCircuitOperatorEvaluator { constructor() { @@ -22,15 +21,9 @@ export class AndOperatorEvaluator extends BooleanShortCircuitOperatorEvaluator { return leftValue && rightValue; } override polarsDoEvaluate( - leftValue: boolean | PolarsInternal, - rightValue: boolean | PolarsInternal, - ): boolean | PolarsInternal { - if (BOOLEAN_TYPEGUARD(leftValue)) { - if (BOOLEAN_TYPEGUARD(rightValue)) { - return this.polarsDoEvaluate(leftValue, rightValue); - } - return rightValue.and(leftValue); - } + leftValue: PolarsInternal, + rightValue: PolarsInternal, + ): PolarsInternal { return leftValue.and(rightValue); } } diff --git a/libs/language-server/src/lib/ast/expressions/evaluators/division-operator-evaluator.ts b/libs/language-server/src/lib/ast/expressions/evaluators/division-operator-evaluator.ts index 1c613cfa..258cd355 100644 --- a/libs/language-server/src/lib/ast/expressions/evaluators/division-operator-evaluator.ts +++ b/libs/language-server/src/lib/ast/expressions/evaluators/division-operator-evaluator.ts @@ -40,26 +40,9 @@ export class DivisionOperatorEvaluator extends DefaultBinaryOperatorEvaluator< } override polarsDoEvaluate( - left: number | PolarsInternal, - right: number | PolarsInternal, - expression: BinaryExpression, - context: ValidationContext | undefined, - ): number | PolarsInternal | undefined { - if (NUMBER_TYPEGUARD(left)) { - if (NUMBER_TYPEGUARD(right)) { - return this.doEvaluate(left, right, expression, context); - } - context?.accept( - 'warning', - ` / is not fully supported yet. Using a hack`, - { - node: expression, - }, - ); - // HACK: - const one = right.div(right); - return one.mul(left).div(right); - } + left: PolarsInternal, + right: PolarsInternal, + ): PolarsInternal { return left.div(right); } } diff --git a/libs/language-server/src/lib/ast/expressions/evaluators/equality-operator-evaluator.ts b/libs/language-server/src/lib/ast/expressions/evaluators/equality-operator-evaluator.ts index 8e72e469..bd194369 100644 --- a/libs/language-server/src/lib/ast/expressions/evaluators/equality-operator-evaluator.ts +++ b/libs/language-server/src/lib/ast/expressions/evaluators/equality-operator-evaluator.ts @@ -28,14 +28,9 @@ export class EqualityOperatorEvaluator extends DefaultBinaryOperatorEvaluator< return left === right; } override polarsDoEvaluate( - left: InternalValueRepresentation | PolarsInternal, - right: InternalValueRepresentation | PolarsInternal, - ): boolean | PolarsInternal { - if (INTERNAL_VALUE_REPRESENTATION_TYPEGUARD(left)) { - return INTERNAL_VALUE_REPRESENTATION_TYPEGUARD(right) - ? this.doEvaluate(left, right) - : right.eq(left); - } + left: PolarsInternal, + right: PolarsInternal, + ): PolarsInternal { return left.eq(right); } } diff --git a/libs/language-server/src/lib/ast/expressions/evaluators/greater-equal-operator-evaluator.ts b/libs/language-server/src/lib/ast/expressions/evaluators/greater-equal-operator-evaluator.ts index 1b4b1377..2625eeba 100644 --- a/libs/language-server/src/lib/ast/expressions/evaluators/greater-equal-operator-evaluator.ts +++ b/libs/language-server/src/lib/ast/expressions/evaluators/greater-equal-operator-evaluator.ts @@ -18,14 +18,9 @@ export class GreaterEqualOperatorEvaluator extends DefaultBinaryOperatorEvaluato return leftValue >= rightValue; } override polarsDoEvaluate( - left: number | PolarsInternal, - right: number | PolarsInternal, - ): boolean | PolarsInternal { - if (NUMBER_TYPEGUARD(left)) { - return NUMBER_TYPEGUARD(right) - ? this.doEvaluate(left, right) - : right.lt(left); - } + left: PolarsInternal, + right: PolarsInternal, + ): PolarsInternal { return left.gtEq(right); } } diff --git a/libs/language-server/src/lib/ast/expressions/evaluators/greater-than-operator-evaluator.ts b/libs/language-server/src/lib/ast/expressions/evaluators/greater-than-operator-evaluator.ts index 29af7ac5..2139950b 100644 --- a/libs/language-server/src/lib/ast/expressions/evaluators/greater-than-operator-evaluator.ts +++ b/libs/language-server/src/lib/ast/expressions/evaluators/greater-than-operator-evaluator.ts @@ -18,14 +18,9 @@ export class GreaterThanOperatorEvaluator extends DefaultBinaryOperatorEvaluator return leftValue > rightValue; } override polarsDoEvaluate( - left: number | PolarsInternal, - right: number | PolarsInternal, - ): boolean | PolarsInternal { - if (NUMBER_TYPEGUARD(left)) { - return NUMBER_TYPEGUARD(right) - ? this.doEvaluate(left, right) - : right.ltEq(left); - } + left: PolarsInternal, + right: PolarsInternal, + ): PolarsInternal { return left.gt(right); } } diff --git a/libs/language-server/src/lib/ast/expressions/evaluators/in-operator-evaluator.ts b/libs/language-server/src/lib/ast/expressions/evaluators/in-operator-evaluator.ts index 18100075..9f031f2b 100644 --- a/libs/language-server/src/lib/ast/expressions/evaluators/in-operator-evaluator.ts +++ b/libs/language-server/src/lib/ast/expressions/evaluators/in-operator-evaluator.ts @@ -2,12 +2,9 @@ // // SPDX-License-Identifier: AGPL-3.0-only -import { type BinaryExpression } from '../..'; -import { type ValidationContext } from '../../..'; import { type InternalValueRepresentation, type InternalValueRepresentationTypeguard, - type PolarsInternal, } from '../internal-value-representation'; import { DefaultBinaryOperatorEvaluator } from '../operator-evaluator'; import { NUMBER_TYPEGUARD, STRING_TYPEGUARD } from '../typeguards'; @@ -30,20 +27,6 @@ export class InOperatorEvaluator extends DefaultBinaryOperatorEvaluator< ): boolean { return right.includes(left); } - override polarsDoEvaluate( - left: InternalValueRepresentation | PolarsInternal, - right: InternalValueRepresentation[] | PolarsInternal, - expression: BinaryExpression, - context: ValidationContext | undefined, - ): boolean | PolarsInternal | undefined { - if ( - isLeftOperandMatchingValueRepresentationTypeguard(left) && - isRightOperandMatchingValueRepresentationTypeguard(right) - ) { - return this.doEvaluate(left, right); - } - return super.polarsDoEvaluate(left, right, expression, context); - } } const isLeftOperandMatchingValueRepresentationTypeguard: InternalValueRepresentationTypeguard< diff --git a/libs/language-server/src/lib/ast/expressions/evaluators/inequality-operator-evaluator.ts b/libs/language-server/src/lib/ast/expressions/evaluators/inequality-operator-evaluator.ts index 26bdcce3..50d976ab 100644 --- a/libs/language-server/src/lib/ast/expressions/evaluators/inequality-operator-evaluator.ts +++ b/libs/language-server/src/lib/ast/expressions/evaluators/inequality-operator-evaluator.ts @@ -28,14 +28,9 @@ export class InequalityOperatorEvaluator extends DefaultBinaryOperatorEvaluator< return left !== right; } override polarsDoEvaluate( - left: InternalValueRepresentation | PolarsInternal, - right: InternalValueRepresentation | PolarsInternal, - ): boolean | PolarsInternal { - if (INTERNAL_VALUE_REPRESENTATION_TYPEGUARD(left)) { - return INTERNAL_VALUE_REPRESENTATION_TYPEGUARD(right) - ? this.doEvaluate(left, right) - : right.neq(left); - } + left: PolarsInternal, + right: PolarsInternal, + ): PolarsInternal { return left.neq(right); } } diff --git a/libs/language-server/src/lib/ast/expressions/evaluators/less-equal-operator-evaluator.ts b/libs/language-server/src/lib/ast/expressions/evaluators/less-equal-operator-evaluator.ts index 8351601a..ba0d5883 100644 --- a/libs/language-server/src/lib/ast/expressions/evaluators/less-equal-operator-evaluator.ts +++ b/libs/language-server/src/lib/ast/expressions/evaluators/less-equal-operator-evaluator.ts @@ -18,14 +18,9 @@ export class LessEqualOperatorEvaluator extends DefaultBinaryOperatorEvaluator< return leftValue <= rightValue; } override polarsDoEvaluate( - left: number | PolarsInternal, - right: number | PolarsInternal, - ): boolean | PolarsInternal { - if (NUMBER_TYPEGUARD(left)) { - return NUMBER_TYPEGUARD(right) - ? this.doEvaluate(left, right) - : right.gt(left); - } + left: PolarsInternal, + right: PolarsInternal, + ): PolarsInternal { return left.ltEq(right); } } diff --git a/libs/language-server/src/lib/ast/expressions/evaluators/less-than-operator-evaluator.ts b/libs/language-server/src/lib/ast/expressions/evaluators/less-than-operator-evaluator.ts index de39f465..ca1ce6f4 100644 --- a/libs/language-server/src/lib/ast/expressions/evaluators/less-than-operator-evaluator.ts +++ b/libs/language-server/src/lib/ast/expressions/evaluators/less-than-operator-evaluator.ts @@ -18,14 +18,9 @@ export class LessThanOperatorEvaluator extends DefaultBinaryOperatorEvaluator< return leftValue < rightValue; } override polarsDoEvaluate( - left: number | PolarsInternal, - right: number | PolarsInternal, - ): boolean | PolarsInternal { - if (NUMBER_TYPEGUARD(left)) { - return NUMBER_TYPEGUARD(right) - ? this.doEvaluate(left, right) - : right.gtEq(left); - } + left: PolarsInternal, + right: PolarsInternal, + ): PolarsInternal { return left.lt(right); } } diff --git a/libs/language-server/src/lib/ast/expressions/evaluators/minus-operator-evaluator.ts b/libs/language-server/src/lib/ast/expressions/evaluators/minus-operator-evaluator.ts index ee19bcea..aafff203 100644 --- a/libs/language-server/src/lib/ast/expressions/evaluators/minus-operator-evaluator.ts +++ b/libs/language-server/src/lib/ast/expressions/evaluators/minus-operator-evaluator.ts @@ -2,6 +2,7 @@ // // SPDX-License-Identifier: AGPL-3.0-only +import { type PolarsInternal } from '../internal-value-representation'; import { DefaultUnaryOperatorEvaluator } from '../operator-evaluator'; import { NUMBER_TYPEGUARD } from '../typeguards'; @@ -15,4 +16,8 @@ export class MinusOperatorEvaluator extends DefaultUnaryOperatorEvaluator< override doEvaluate(operandValue: number): number { return -operandValue; } + protected override polarsDoEvaluate(operand: PolarsInternal): PolarsInternal { + // HACK: Polars does not support neg + return operand.mul(-1); + } } diff --git a/libs/language-server/src/lib/ast/expressions/evaluators/modulo-operator-evaluator.ts b/libs/language-server/src/lib/ast/expressions/evaluators/modulo-operator-evaluator.ts index 146f3e1a..ba211cb5 100644 --- a/libs/language-server/src/lib/ast/expressions/evaluators/modulo-operator-evaluator.ts +++ b/libs/language-server/src/lib/ast/expressions/evaluators/modulo-operator-evaluator.ts @@ -41,26 +41,9 @@ export class ModuloOperatorEvaluator extends DefaultBinaryOperatorEvaluator< } override polarsDoEvaluate( - left: number | PolarsInternal, - right: number | PolarsInternal, - expression: BinaryExpression, - context: ValidationContext | undefined, - ): number | PolarsInternal | undefined { - if (NUMBER_TYPEGUARD(left)) { - if (NUMBER_TYPEGUARD(right)) { - return this.doEvaluate(left, right, expression, context); - } - context?.accept( - 'warning', - ` - is not fully supported yet. Using a hack`, - { - node: expression, - }, - ); - // HACK: - const zero = right.mul(0); - return zero.add(left).modulo(right); - } + left: PolarsInternal, + right: PolarsInternal, + ): PolarsInternal | undefined { return left.modulo(right); } } diff --git a/libs/language-server/src/lib/ast/expressions/evaluators/multiplication-operator-evaluator.ts b/libs/language-server/src/lib/ast/expressions/evaluators/multiplication-operator-evaluator.ts index 5647874e..18290be5 100644 --- a/libs/language-server/src/lib/ast/expressions/evaluators/multiplication-operator-evaluator.ts +++ b/libs/language-server/src/lib/ast/expressions/evaluators/multiplication-operator-evaluator.ts @@ -18,14 +18,9 @@ export class MultiplicationOperatorEvaluator extends DefaultBinaryOperatorEvalua return leftValue * rightValue; } override polarsDoEvaluate( - left: number | PolarsInternal, - right: number | PolarsInternal, - ): number | PolarsInternal { - if (NUMBER_TYPEGUARD(left)) { - return NUMBER_TYPEGUARD(right) - ? this.doEvaluate(left, right) - : right.mul(left); - } + left: PolarsInternal, + right: PolarsInternal, + ): PolarsInternal { return left.mul(right); } } diff --git a/libs/language-server/src/lib/ast/expressions/evaluators/not-operator-evaluator.ts b/libs/language-server/src/lib/ast/expressions/evaluators/not-operator-evaluator.ts index 809d711f..d9b9c5d0 100644 --- a/libs/language-server/src/lib/ast/expressions/evaluators/not-operator-evaluator.ts +++ b/libs/language-server/src/lib/ast/expressions/evaluators/not-operator-evaluator.ts @@ -17,7 +17,7 @@ export class NotOperatorEvaluator extends DefaultUnaryOperatorEvaluator< return !operandValue; } - override polarsDoEvaluate(col: PolarsInternal): PolarsInternal { - return col.not(); + override polarsDoEvaluate(operand: PolarsInternal): PolarsInternal { + return operand.not(); } } diff --git a/libs/language-server/src/lib/ast/expressions/evaluators/or-operator-evaluator.ts b/libs/language-server/src/lib/ast/expressions/evaluators/or-operator-evaluator.ts index c6743dcb..befb7022 100644 --- a/libs/language-server/src/lib/ast/expressions/evaluators/or-operator-evaluator.ts +++ b/libs/language-server/src/lib/ast/expressions/evaluators/or-operator-evaluator.ts @@ -4,7 +4,6 @@ import { type PolarsInternal } from '../internal-value-representation'; import { BooleanShortCircuitOperatorEvaluator } from '../operator-evaluator'; -import { BOOLEAN_TYPEGUARD } from '../typeguards'; export class OrOperatorEvaluator extends BooleanShortCircuitOperatorEvaluator { constructor() { @@ -23,15 +22,9 @@ export class OrOperatorEvaluator extends BooleanShortCircuitOperatorEvaluator { } override polarsDoEvaluate( - leftValue: boolean | PolarsInternal, - rightValue: boolean | PolarsInternal, - ): boolean | PolarsInternal { - if (BOOLEAN_TYPEGUARD(leftValue)) { - if (BOOLEAN_TYPEGUARD(rightValue)) { - return this.polarsDoEvaluate(leftValue, rightValue); - } - return rightValue.or(leftValue); - } + leftValue: PolarsInternal, + rightValue: PolarsInternal, + ): PolarsInternal { return leftValue.or(rightValue); } } diff --git a/libs/language-server/src/lib/ast/expressions/evaluators/plus-operator-evaluator.ts b/libs/language-server/src/lib/ast/expressions/evaluators/plus-operator-evaluator.ts index 9e147dc0..875a50dc 100644 --- a/libs/language-server/src/lib/ast/expressions/evaluators/plus-operator-evaluator.ts +++ b/libs/language-server/src/lib/ast/expressions/evaluators/plus-operator-evaluator.ts @@ -17,7 +17,7 @@ export class PlusOperatorEvaluator extends DefaultUnaryOperatorEvaluator< return operandValue; } - protected override polarsDoEvaluate(col: PolarsInternal): PolarsInternal { - return col; + protected override polarsDoEvaluate(operand: PolarsInternal): PolarsInternal { + return operand; } } diff --git a/libs/language-server/src/lib/ast/expressions/evaluators/pow-operator-evaluator.ts b/libs/language-server/src/lib/ast/expressions/evaluators/pow-operator-evaluator.ts index 16732880..dffaad5f 100644 --- a/libs/language-server/src/lib/ast/expressions/evaluators/pow-operator-evaluator.ts +++ b/libs/language-server/src/lib/ast/expressions/evaluators/pow-operator-evaluator.ts @@ -41,36 +41,4 @@ export class PowOperatorEvaluator extends DefaultBinaryOperatorEvaluator< } return resultingValue; } - - override polarsDoEvaluate( - leftValue: number | PolarsInternal, - rightValue: number | PolarsInternal, - expression: BinaryExpression, - context: ValidationContext | undefined, - ): number | PolarsInternal | undefined { - if (NUMBER_TYPEGUARD(leftValue)) { - if (NUMBER_TYPEGUARD(rightValue)) { - return this.doEvaluate(leftValue, rightValue, expression, context); - } - context?.accept( - 'error', - ' pow is not supported yet', - { - node: expression.right, - }, - ); - return undefined; - } - if (NUMBER_TYPEGUARD(rightValue)) { - return leftValue.pow(rightValue); - } - context?.accept( - 'error', - ' pow is not supported yet', - { - node: expression, - }, - ); - return undefined; - } } diff --git a/libs/language-server/src/lib/ast/expressions/evaluators/root-operator-evaluator.ts b/libs/language-server/src/lib/ast/expressions/evaluators/root-operator-evaluator.ts index 76b395b1..e628e30c 100644 --- a/libs/language-server/src/lib/ast/expressions/evaluators/root-operator-evaluator.ts +++ b/libs/language-server/src/lib/ast/expressions/evaluators/root-operator-evaluator.ts @@ -2,7 +2,6 @@ // // SPDX-License-Identifier: AGPL-3.0-only -import { PolarsInternal } from '..'; import { type ValidationContext } from '../../../validation/validation-context'; import { type BinaryExpression } from '../../generated/ast'; import { DefaultBinaryOperatorEvaluator } from '../operator-evaluator'; @@ -45,36 +44,4 @@ export class RootOperatorEvaluator extends DefaultBinaryOperatorEvaluator< } return resultingValue; } - - override polarsDoEvaluate( - leftValue: number | PolarsInternal, - rightValue: number | PolarsInternal, - expression: BinaryExpression, - context: ValidationContext | undefined, - ): number | PolarsInternal | undefined { - if (NUMBER_TYPEGUARD(leftValue)) { - if (NUMBER_TYPEGUARD(rightValue)) { - return this.doEvaluate(leftValue, rightValue, expression, context); - } - context?.accept( - 'error', - ' root is not supported yet', - { - node: expression.right, - }, - ); - return undefined; - } - if (NUMBER_TYPEGUARD(rightValue)) { - return leftValue.pow(1 / rightValue); - } - context?.accept( - 'error', - ' root is not supported yet', - { - node: expression, - }, - ); - return undefined; - } } diff --git a/libs/language-server/src/lib/ast/expressions/evaluators/sqrt-operator-evaluator.ts b/libs/language-server/src/lib/ast/expressions/evaluators/sqrt-operator-evaluator.ts index 1c169fc9..467b7aeb 100644 --- a/libs/language-server/src/lib/ast/expressions/evaluators/sqrt-operator-evaluator.ts +++ b/libs/language-server/src/lib/ast/expressions/evaluators/sqrt-operator-evaluator.ts @@ -7,6 +7,7 @@ import { strict as assert } from 'assert'; import { type ValidationContext } from '../../../validation/validation-context'; import { type UnaryExpression } from '../../generated/ast'; +import { type PolarsInternal } from '../internal-value-representation'; import { DefaultUnaryOperatorEvaluator } from '../operator-evaluator'; import { NUMBER_TYPEGUARD } from '../typeguards'; @@ -35,4 +36,9 @@ export class SqrtOperatorEvaluator extends DefaultUnaryOperatorEvaluator< } return resultingValue; } + + protected override polarsDoEvaluate(operand: PolarsInternal): PolarsInternal { + // HACK: Typst does not have a root expression + return operand.pow(1 / 2); + } } diff --git a/libs/language-server/src/lib/ast/expressions/evaluators/subtraction-operator-evaluator.ts b/libs/language-server/src/lib/ast/expressions/evaluators/subtraction-operator-evaluator.ts index 6181aa09..e35a4dd6 100644 --- a/libs/language-server/src/lib/ast/expressions/evaluators/subtraction-operator-evaluator.ts +++ b/libs/language-server/src/lib/ast/expressions/evaluators/subtraction-operator-evaluator.ts @@ -1,8 +1,6 @@ // SPDX-FileCopyrightText: 2023 Friedrich-Alexander-Universitat Erlangen-Nurnberg // // SPDX-License-Identifier: AGPL-3.0-only -import { type ValidationContext } from '../../../validation/validation-context'; -import { type BinaryExpression } from '../../generated/ast'; import { type PolarsInternal } from '../internal-value-representation'; import { DefaultBinaryOperatorEvaluator } from '../operator-evaluator'; import { NUMBER_TYPEGUARD } from '../typeguards'; @@ -19,26 +17,9 @@ export class SubtractionOperatorEvaluator extends DefaultBinaryOperatorEvaluator return leftValue - rightValue; } override polarsDoEvaluate( - left: number | PolarsInternal, - right: number | PolarsInternal, - expression: BinaryExpression, - context: ValidationContext | undefined, - ): number | PolarsInternal { - if (NUMBER_TYPEGUARD(left)) { - if (NUMBER_TYPEGUARD(right)) { - return this.doEvaluate(left, right); - } - context?.accept( - 'warning', - ` - is not fully supported yet. Using a hack`, - { - node: expression, - }, - ); - // HACK: - const zero = right.mul(0); - return zero.add(left).minus(right); - } + left: PolarsInternal, + right: PolarsInternal, + ): PolarsInternal { return left.minus(right); } } diff --git a/libs/language-server/src/lib/ast/expressions/evaluators/xor-operator-evaluator.ts b/libs/language-server/src/lib/ast/expressions/evaluators/xor-operator-evaluator.ts index 03bfdd9a..8531c3ac 100644 --- a/libs/language-server/src/lib/ast/expressions/evaluators/xor-operator-evaluator.ts +++ b/libs/language-server/src/lib/ast/expressions/evaluators/xor-operator-evaluator.ts @@ -18,18 +18,10 @@ export class XorOperatorEvaluator extends DefaultBinaryOperatorEvaluator< return (leftValue && !rightValue) || (!leftValue && rightValue); } override polarsDoEvaluate( - leftValue: boolean | PolarsInternal, - rightValue: boolean | PolarsInternal, - ): boolean | PolarsInternal { + leftValue: PolarsInternal, + rightValue: PolarsInternal, + ): PolarsInternal { // HACK: There should be an xor expression in polars - if (BOOLEAN_TYPEGUARD(leftValue)) { - return BOOLEAN_TYPEGUARD(rightValue) - ? this.doEvaluate(leftValue, rightValue) - : rightValue.and(!leftValue).or(rightValue.not().and(leftValue)); - } - if (BOOLEAN_TYPEGUARD(rightValue)) { - return leftValue.and(!rightValue).or(leftValue.not().and(rightValue)); - } return leftValue.and(rightValue.not()).or(leftValue.not().and(rightValue)); } } diff --git a/libs/language-server/src/lib/ast/expressions/operator-evaluator.ts b/libs/language-server/src/lib/ast/expressions/operator-evaluator.ts index 8f10d4d0..21251a07 100644 --- a/libs/language-server/src/lib/ast/expressions/operator-evaluator.ts +++ b/libs/language-server/src/lib/ast/expressions/operator-evaluator.ts @@ -62,7 +62,7 @@ export interface PolarsOperatorEvaluator< wrapperFactories: WrapperFactoryProvider, strategy: EvaluationStrategy, validationContext: ValidationContext | undefined, - ): InternalValueRepresentation | PolarsInternal | undefined; + ): PolarsInternal | undefined; } export abstract class DefaultUnaryOperatorEvaluator< @@ -80,7 +80,7 @@ export abstract class DefaultUnaryOperatorEvaluator< wrapperFactories: WrapperFactoryProvider, strategy: EvaluationStrategy, validationContext: ValidationContext | undefined, - ): InternalValueRepresentation | PolarsInternal | undefined { + ): PolarsInternal | undefined { assert(expression.operator === this.operator); const operandValue = polarsEvaluateExpression( expression.expression, @@ -93,10 +93,6 @@ export abstract class DefaultUnaryOperatorEvaluator< return undefined; } - if (this.operandValueTypeguard(operandValue)) { - return this.doEvaluate(operandValue, expression, validationContext); - } - assert(!INTERNAL_VALUE_REPRESENTATION_TYPEGUARD(operandValue)); return this.polarsDoEvaluate(operandValue, expression, validationContext); } @@ -107,13 +103,10 @@ export abstract class DefaultUnaryOperatorEvaluator< ): T | undefined; protected polarsDoEvaluate( - operand: PolarsInternal, + _operand: PolarsInternal, expression: UnaryExpression, context: ValidationContext | undefined, - ): T | PolarsInternal | undefined { - if (this.operandValueTypeguard(operand)) { - return this.doEvaluate(operand, expression, context); - } + ): PolarsInternal | undefined { context?.accept('error', `${expression.operator} is not supported yet.`, { node: expression, }); @@ -165,14 +158,11 @@ export abstract class DefaultBinaryOperatorEvaluator< ): T | undefined; protected polarsDoEvaluate( - left: L | PolarsInternal, - right: R | PolarsInternal, + _left: PolarsInternal, + _right: PolarsInternal, expression: BinaryExpression, context: ValidationContext | undefined, - ): T | PolarsInternal | undefined { - if (this.leftValueTypeguard(left) && this.rightValueTypeguard(right)) { - return this.doEvaluate(left, right, expression, context); - } + ): PolarsInternal | undefined { context?.accept('error', `${expression.operator} is not supported yet.`, { node: expression, }); @@ -225,7 +215,7 @@ export abstract class DefaultBinaryOperatorEvaluator< wrapperFactories: WrapperFactoryProvider, strategy: EvaluationStrategy, validationContext: ValidationContext | undefined, - ): InternalValueRepresentation | PolarsInternal | undefined { + ): PolarsInternal | undefined { assert(expression.operator === this.operator); const leftValue = polarsEvaluateExpression( expression.left, @@ -248,13 +238,6 @@ export abstract class DefaultBinaryOperatorEvaluator< return undefined; } - if (INTERNAL_VALUE_REPRESENTATION_TYPEGUARD(leftValue)) { - assert(this.leftValueTypeguard(leftValue)); - } - if (INTERNAL_VALUE_REPRESENTATION_TYPEGUARD(rightValue)) { - assert(this.rightValueTypeguard(rightValue)); - } - return this.polarsDoEvaluate( leftValue, rightValue, @@ -283,11 +266,11 @@ export abstract class BooleanShortCircuitOperatorEvaluator ): boolean; protected polarsDoEvaluate( - _left: boolean | PolarsInternal, - _right: boolean | PolarsInternal, + _left: PolarsInternal, + _right: PolarsInternal, expression: BinaryExpression, context: ValidationContext | undefined, - ): boolean | PolarsInternal | undefined { + ): PolarsInternal | undefined { context?.accept('error', `${expression.operator} is not supported yet.`, { node: expression, }); @@ -340,30 +323,18 @@ export abstract class BooleanShortCircuitOperatorEvaluator wrapperFactories: WrapperFactoryProvider, strategy: EvaluationStrategy, validationContext: ValidationContext | undefined, - ): boolean | PolarsInternal | undefined { + ): PolarsInternal | undefined { assert(expression.operator === this.operator); - const leftValue = polarsEvaluateExpression( + const left = polarsEvaluateExpression( expression.left, evaluationContext, wrapperFactories, validationContext, strategy, ); - assert( - leftValue === undefined || - BOOLEAN_TYPEGUARD(leftValue) || - !INTERNAL_VALUE_REPRESENTATION_TYPEGUARD(leftValue), - ); - if (strategy === EvaluationStrategy.LAZY) { - if (leftValue === undefined) { - return undefined; - } - if ( - BOOLEAN_TYPEGUARD(leftValue) && - this.canSkipRightOperandEvaluation(leftValue) - ) { - return this.getShortCircuitValue(); - } + + if (strategy === EvaluationStrategy.LAZY && left === undefined) { + return undefined; } const rightValue = polarsEvaluateExpression( @@ -373,16 +344,12 @@ export abstract class BooleanShortCircuitOperatorEvaluator validationContext, strategy, ); - if (leftValue === undefined || rightValue === undefined) { + if (left === undefined || rightValue === undefined) { return undefined; } - assert( - BOOLEAN_TYPEGUARD(rightValue) || - !INTERNAL_VALUE_REPRESENTATION_TYPEGUARD(rightValue), - ); return this.polarsDoEvaluate( - leftValue, + left, rightValue, expression, validationContext, diff --git a/package.json b/package.json index f841c23a..3f60332b 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,8 @@ "generate": "nx run language-server:generate", "example:cars": "nx run interpreter:run -d example/cars.jv -dg peek", "example:cars-polars": "nx run interpreter:run -d example/cars.jv -dg peek --use-polars", + "example:testing": "nx run interpreter:run -d example/testing.jv -dg peek", + "example:testing-polars": "nx run interpreter:run -d example/testing.jv -dg peek --use-polars", "example:one-block-polars": "nx run interpreter:run -d example/one-block.jv -dg peek --use-polars", "example:gtfs": "nx run interpreter:run -d example/gtfs-static.jv -dg peek", "example:gtfs-rt": "nx run interpreter:run -d example/gtfs-rt.jv -dg peek",