@@ -3,6 +3,7 @@ import * as es from 'estree'
3
3
import * as misc from '../stdlib/misc'
4
4
import { Context , substituterNodes } from '../types'
5
5
import * as ast from '../utils/ast/astCreator'
6
+ import { BuiltInFunctionError } from '../errors/errors'
6
7
import { nodeToValue , nodeToValueWithContext , valueToExpression } from './converter'
7
8
import { codify } from './stepper'
8
9
import { isBuiltinFunction , isNumber } from './util'
@@ -30,13 +31,13 @@ export function stringify(val: substituterNodes): es.Literal {
30
31
// defineBuiltin(context, 'error(str)', misc.error_message)
31
32
export function error ( val : substituterNodes , str ?: substituterNodes ) {
32
33
const output = ( str === undefined ? '' : str + ' ' ) + stringify ( val )
33
- throw new Error ( output )
34
+ throw new BuiltInFunctionError ( output )
34
35
}
35
36
36
37
// defineBuiltin(context, 'prompt(str)', prompt)
37
38
export function prompt ( str : substituterNodes ) : es . Literal {
38
39
if ( str . type !== 'Literal' || typeof str . value !== 'string' ) {
39
- throw new Error ( 'Argument to error must be a string.' )
40
+ throw new BuiltInFunctionError ( 'Argument to error must be a string.' )
40
41
}
41
42
const result = window . prompt ( str . value as string )
42
43
return ast . literal ( ( result ? result : null ) as string )
@@ -99,9 +100,9 @@ export function parse_int(str: substituterNodes, radix: substituterNodes): es.Ex
99
100
export function evaluateMath ( mathFn : string , ...args : substituterNodes [ ] ) : es . Expression {
100
101
const fn = Math [ mathFn . split ( '_' ) [ 1 ] ]
101
102
if ( ! fn ) {
102
- throw new Error ( `Math function ${ mathFn } not found.` )
103
+ throw new BuiltInFunctionError ( `Math function ${ mathFn } not found.` )
103
104
} else if ( args . some ( arg => ! isNumber ( arg ) ) ) {
104
- throw new Error ( `Math functions must be called with number arguments` )
105
+ throw new BuiltInFunctionError ( `Math functions must be called with number arguments` )
105
106
}
106
107
const jsArgs = args . map ( nodeToValue )
107
108
return valueToExpression ( fn ( ...jsArgs ) )
@@ -115,7 +116,7 @@ export function evaluateModuleFunction(
115
116
) : es . Expression {
116
117
const fn = context . runtime . environments [ 0 ] . head [ moduleFn ]
117
118
if ( ! fn ) {
118
- throw new Error ( `Module function ${ moduleFn } not found.` )
119
+ throw new BuiltInFunctionError ( `Module function ${ moduleFn } not found.` )
119
120
}
120
121
const jsArgs = args . map ( arg => nodeToValueWithContext ( arg , context ) )
121
122
return valueToExpression ( fn ( ...jsArgs ) , context )
@@ -126,7 +127,7 @@ export function evaluateModuleFunction(
126
127
// defineBuiltin(context, 'pair(left, right)', list.pair)
127
128
export function pair ( left : substituterNodes , right : substituterNodes ) : es . ArrayExpression {
128
129
if ( left == null || right == null ) {
129
- throw new Error (
130
+ throw new BuiltInFunctionError (
130
131
//Count the number of arguments that are not undefined
131
132
`Expected 2 arguments, but got ${ [ left , right ] . filter ( x => x != undefined ) . length } `
132
133
)
@@ -136,21 +137,24 @@ export function pair(left: substituterNodes, right: substituterNodes): es.ArrayE
136
137
137
138
// defineBuiltin(context, 'is_pair(val)', list.is_pair)
138
139
export function is_pair ( val : substituterNodes ) : es . Literal {
140
+ if ( val == null ) {
141
+ throw new BuiltInFunctionError ( 'Expected 1 argument, but got 0' )
142
+ }
139
143
return ast . literal ( val . type === 'ArrayExpression' && val . elements . length === 2 )
140
144
}
141
145
142
146
// defineBuiltin(context, 'head(xs)', list.head)
143
147
export function head ( xs : substituterNodes ) : es . Expression {
144
148
if ( is_pair ( xs ) . value === false ) {
145
- throw new Error ( `${ codify ( xs ) } is not a pair` )
149
+ throw new BuiltInFunctionError ( `${ codify ( xs ) } is not a pair` )
146
150
}
147
151
return ( xs as es . ArrayExpression ) . elements [ 0 ] as es . Expression
148
152
}
149
153
150
154
// defineBuiltin(context, 'tail(xs)', list.tail)
151
155
export function tail ( xs : substituterNodes ) : es . Expression {
152
156
if ( is_pair ( xs ) . value === false ) {
153
- throw new Error ( `${ codify ( xs ) } is not a pair` )
157
+ throw new BuiltInFunctionError ( `${ codify ( xs ) } is not a pair` )
154
158
}
155
159
return ( xs as es . ArrayExpression ) . elements [ 1 ] as es . Expression
156
160
}
0 commit comments