Skip to content

Commit

Permalink
Make validations work
Browse files Browse the repository at this point in the history
  • Loading branch information
Lotes committed Feb 4, 2025
1 parent fe5f3d8 commit dedc35c
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 6 deletions.
2 changes: 1 addition & 1 deletion examples/expression/src/ast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ export type Model = Array<VariableDeclaration | Printout>;
export type Node = Expression | Printout | VariableDeclaration;

export function isAstNode(node: unknown): node is Node {
return Object.getOwnPropertyNames(node).includes('type') && ['variable-usage', 'unary', 'binary', 'numeric', 'string', 'printout', 'variable-declaration'].includes(node as Node['type']);
return Object.getOwnPropertyNames(node).includes('type') && ['variable-usage', 'unary', 'binary', 'numeric', 'string', 'printout', 'variable-declaration'].includes((node as Node).type);
}

export namespace AST {
Expand Down
23 changes: 22 additions & 1 deletion examples/expression/src/type-system.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import { createTypirServices, InferenceRuleNotApplicable, InferOperatorWithMultipleOperands, InferOperatorWithSingleOperand, NO_PARAMETER_NAME } from 'typir';
import { createTypirServices, InferenceRuleNotApplicable, InferOperatorWithMultipleOperands, InferOperatorWithSingleOperand, isAssignabilityProblem, isInferenceProblem, NO_PARAMETER_NAME, TypirServices, ValidationMessageDetails } from 'typir';
import { BinaryExpression, isAstNode, isBinaryExpression, isNumeric, isPrintout, isUnaryExpression, isVariableDeclaration, isVariableUsage, UnaryExpression } from './ast.js';

export function initializeTypir() {
Expand Down Expand Up @@ -65,5 +65,26 @@ export function initializeTypir() {
return InferenceRuleNotApplicable;
});

typir.validation.Collector.addValidationRule(
(node: unknown) => {
if (isPrintout(node)) {
const actual = typir.Inference.inferType(node.value)!;
if(!Array.isArray(actual)) {
const expected = typeString;
const result = typir.Assignability.getAssignabilityResult(actual, expected);
if(isAssignabilityProblem(result)) {
return [{
$problem: 'ValidationProblem',
languageNode: node,
message: 'Not assignable!',
severity: 'error'
}];
}
}
}
return [];
}
);

return typir;
}
26 changes: 24 additions & 2 deletions examples/expression/src/validator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,30 @@
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import { TypirServices } from 'typir';
import { Model } from './ast.js';
import { Expression, Model } from './ast.js';

export function validate(typir: TypirServices, model: Model, accept: (message: string) => void) {
model.forEach(i => typir.validation.Collector.validate(i).forEach(m => accept(m.message)));
function runValidator(languageNode: unknown) {
typir.validation.Collector.validate(languageNode).forEach(m => accept(m.message));
}
function visitExpression(expr: Expression) {
switch(expr.type) {
case 'binary':
visitExpression(expr.left);
visitExpression(expr.right);
break;
case 'unary':
visitExpression(expr.operand);
break;
case 'variable-usage':
case 'numeric':
case 'string':
break;
}
runValidator(expr);
}
for (const statement of model) {
visitExpression(statement.value);
runValidator(statement);
}
}
6 changes: 4 additions & 2 deletions examples/expression/test/validator.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@ import { validate } from '../src/validator.js';
const typir = initializeTypir();

describe('Validator', () => {
test('quak', () => {
expectValidationMessages('PRINT 1;');
test('Positives', () => {
expectValidationMessages('PRINT 1+2+3;');
expectValidationMessages('PRINT "Hallo!";');
expectValidationMessages('PRINT "Hallo!"+"Welt!";');
});
});

Expand Down

0 comments on commit dedc35c

Please sign in to comment.