diff options
author | Elizabeth Hunt <elizabeth.hunt@simponic.xyz> | 2024-02-28 14:59:28 -0500 |
---|---|---|
committer | simponic <elizabeth.hunt@simponic.xyz> | 2024-02-28 14:59:28 -0500 |
commit | 7cc3ef5fa1feec8087618c899441a11052f84c48 (patch) | |
tree | 6d65d585fcf61e9cee7193dfb2af4d719074f732 /src/interpreter/denotable.ts | |
parent | c8336ee48791f00378a35e463e2962f4c856beb2 (diff) | |
download | cps-interpreter-7cc3ef5fa1feec8087618c899441a11052f84c48.tar.gz cps-interpreter-7cc3ef5fa1feec8087618c899441a11052f84c48.zip |
builtin_match_signatures (#1)
Co-authored-by: Lizzy Hunt <lizzy.hunt@usu.edu>
Reviewed-on: https://git.simponic.xyz/simponic/cps-interpreter/pulls/1
Co-authored-by: Elizabeth Hunt <elizabeth.hunt@simponic.xyz>
Co-committed-by: Elizabeth Hunt <elizabeth.hunt@simponic.xyz>
Diffstat (limited to 'src/interpreter/denotable.ts')
-rw-r--r-- | src/interpreter/denotable.ts | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/src/interpreter/denotable.ts b/src/interpreter/denotable.ts new file mode 100644 index 0000000..65aee86 --- /dev/null +++ b/src/interpreter/denotable.ts @@ -0,0 +1,93 @@ +import type { Identifier } from '@/parser'; +import { testingLogger } from '@t/logger'; + +export type UnionDenotableType = + | Array<DenotableType | DenotableFunctionSignature> + | DenotableType + | DenotableFunctionSignature + | Array<UnionDenotableType>; + +export type DenotableFunctionSignature = { + arguments: Array<UnionDenotableType>; + return: DenotableType; +}; + +export type DenotableFunction = { + signatures: Array<DenotableFunctionSignature>; + body: Function; +}; + +export type DenotableType = + | 'null' + | 'int' + | 'real' + | 'string' + | 'bytearray' + | 'function' + | 'reference'; + +export type DenotableValue = + | null + | number + | string + | Uint8Array + | DenotableFunction + | Identifier; + +export type Denotable = { + type: DenotableType; + value: DenotableValue; +}; + +export const denotableTypesEquivalent = ( + a: UnionDenotableType, + b: UnionDenotableType, +): boolean => { + if (typeof a !== typeof b) return false; + + if (Array.isArray(a) && Array.isArray(b)) { + if (a.length !== b.length) return false; + for (let i = 0; i < a.length; i++) { + if (!denotableTypesEquivalent(a[i], b[i])) return false; + } + return true; + } + + if ( + typeof a === 'object' && + typeof b === 'object' && + 'arguments' in a && + 'arguments' in b + ) { + if (a.arguments.length !== b.arguments.length) return false; + if (!denotableTypesEquivalent(a.return, b.return)) return false; + for (let i = 0; i < a.arguments.length; i++) { + if (!denotableTypesEquivalent(a.arguments[i], b.arguments[i])) { + return false; + } + } + return true; + } + + if (a === b) return true; + + return false; +}; + +export const matchSignature = ( + args: Array<UnionDenotableType>, + signatures: Array<DenotableFunctionSignature>, +): DenotableFunctionSignature | undefined => { + return signatures.find(signature => { + if (args.length !== signature.arguments.length) return false; + + return args.every((arg, i) => { + const argSignature = signature.arguments[i]; + if (Array.isArray(argSignature)) { + return argSignature.some(a => denotableTypesEquivalent(a, arg)); + } + + return denotableTypesEquivalent(arg, signature.arguments[i]); + }); + }); +}; |