From 51e7319d3ce431ab40f75e7d425134b1ad35ebee Mon Sep 17 00:00:00 2001 From: R-unic Date: Sat, 7 Oct 2023 02:35:06 -0400 Subject: [PATCH] feat: better errors for invalid argument types --- README.md | 3 ++- src/code-analysis/type-checker/index.ts | 5 +++-- src/runtime/intrinsics/eval.ts | 6 +++--- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 408866ac..10b7557e 100644 --- a/README.md +++ b/README.md @@ -74,7 +74,7 @@ yarn run - Basics (numbers, strings, booleans) - String interpolations - Array literals/types - - Object literals + - Object literals/types - Array indexing - Binary expressions (including compound assignment) - Unary expressions (including `++` and `--`) @@ -87,4 +87,5 @@ yarn run - Type aliases (e.x. `type number = int | float`) - `typeof`, `is` - `value is in array` +- Type guards (`value is T`, `"property" is in object`) - Classes \ No newline at end of file diff --git a/src/code-analysis/type-checker/index.ts b/src/code-analysis/type-checker/index.ts index 9ba0a062..6b0c133c 100644 --- a/src/code-analysis/type-checker/index.ts +++ b/src/code-analysis/type-checker/index.ts @@ -131,10 +131,11 @@ export class TypeChecker implements AST.Visitor.BoundExpression, AST.Visit this.check(expr.callee); const type = expr.callee.type; - const expectedTypes = Array.from(type.parameterTypes.values()); + const expectedTypes = Array.from(type.parameterTypes.entries()); for (const arg of expr.args) { + const [parameterName, expectedType] = expectedTypes[expr.args.indexOf(arg)]; this.check(arg); - this.assert(arg, arg.type, expectedTypes[expr.args.indexOf(arg)]); + this.assert(arg, arg.type, expectedType, `Argument type '${arg.type.toString()}' is not assignable to type '${expectedType.toString()}' of parameter '${parameterName}'`); } } diff --git a/src/runtime/intrinsics/eval.ts b/src/runtime/intrinsics/eval.ts index 430406c2..0dbad74e 100644 --- a/src/runtime/intrinsics/eval.ts +++ b/src/runtime/intrinsics/eval.ts @@ -5,12 +5,12 @@ import Intrinsic from "../values/intrinsic"; export default class Eval extends Intrinsic.Function { public readonly name = "eval"; public readonly returnType = new SingularType("any"); - public readonly argumentTypes = { code: new SingularType("string") }; + public readonly argumentTypes = { source: new SingularType("string") }; - public call(code: string): ValueType { + public call(source: string): ValueType { const enclosingResultOutputEnabled = this.interpreter!.host.executionOptions.outputResult; this.interpreter!.host.executionOptions.outputResult = false; - const result = this.interpreter!.host.doString(code); + const result = this.interpreter!.host.doString(source); this.interpreter!.host.executionOptions.outputResult = enclosingResultOutputEnabled; return result; }