11import type {
22 PSEnv ,
3- PSFn ,
43 PSLiteral ,
54 PSMap ,
65 PSMapKey ,
@@ -9,8 +8,8 @@ import type {
98} from "./types.ts" ;
109import type { Operation } from "./deps.ts" ;
1110
12- import { parseYAML } from "./deps .ts" ;
13- import { yaml2ps } from "./convert .ts" ;
11+ import { read } from "./read .ts" ;
12+ import { recognize } from "./recognize .ts" ;
1413import { concat , lookup , map , Maybe } from "./psmap.ts" ;
1514import * as data from "./data.ts" ;
1615
@@ -19,7 +18,7 @@ type Segment = {
1918 value : string ;
2019} | {
2120 type : "expr" ;
22- ref : PSLiteral ;
21+ ref : PSValue ;
2322} ;
2423
2524function * segments ( t : PSTemplate ) : Generator < Segment > {
@@ -28,7 +27,7 @@ function* segments(t: PSTemplate): Generator<Segment> {
2827 let idx = 0 ;
2928 for ( let expr of expressions ) {
3029 let [ start , end ] = expr . range ;
31- let substr = t . value . slice ( idx , start ) ;
30+ let substr = t . value . value . slice ( idx , start ) ;
3231 yield {
3332 type : "const" ,
3433 value : substr ,
@@ -39,16 +38,16 @@ function* segments(t: PSTemplate): Generator<Segment> {
3938 } ;
4039 idx = end ;
4140 }
42- if ( idx < t . value . length ) {
41+ if ( idx < t . value . value . length ) {
4342 yield {
4443 type : "const" ,
45- value : t . value . slice ( idx ) ,
44+ value : t . value . value . slice ( idx ) ,
4645 } ;
4746 }
4847 } else {
4948 yield {
5049 type : "const" ,
51- value : t . value ,
50+ value : t . value . value ,
5251 } ;
5352 }
5453}
@@ -59,7 +58,7 @@ export function createYSEnv(parent = global): PSEnv {
5958 let scope = concat ( parent , context ) ;
6059 let env = createYSEnv ( scope ) ;
6160
62- let value = yield * bind ( $value , scope , [ ] ) ;
61+ let value = yield * bind ( recognize ( $value ) , scope , [ ] ) ;
6362
6463 if ( value . type === "ref" ) {
6564 return value ;
@@ -82,7 +81,7 @@ export function createYSEnv(parent = global): PSEnv {
8281 `${ fn . value } is not a function. It is of type '${ fn . type } '` ,
8382 ) ;
8483 }
85- return yield * env . call ( fn , arg , rest ) ;
84+ return yield * env . call ( fn , yield * env . eval ( arg ) , rest ) ;
8685 } else if ( value . type === "map" ) {
8786 let entries : [ PSMapKey , PSValue ] [ ] = [ ] ;
8887 for ( let [ k , v ] of value . value . entries ( ) ) {
@@ -179,52 +178,8 @@ export const global: PSMap = {
179178 ] ) ,
180179} ;
181180
182- export function parse ( source : string , filename = "script" ) : PSLiteral < PSValue > {
183- let yaml = parseYAML ( source , { filename } ) ;
184- let [ error ] = yaml . errors ;
185- if ( ! yaml ) {
186- throw new SyntaxError ( `empty string is not a YAML Document` ) ;
187- } else if ( error ) {
188- throw error ;
189- }
190- return yaml2ps ( yaml ) ;
191- }
192-
193- export function strip ( literal : PSValue ) : PSValue {
194- //@ts -expect-error stripping is safe because we're just dropping the node
195- let { node : _ , ...value } = literal ;
196- if ( value . type === "map" ) {
197- let map = value . value ;
198- return {
199- type : "map" ,
200- value : new Map (
201- [ ...map . entries ( ) ] . map ( ( [ k , v ] ) => [ strip ( k ) as PSMapKey , strip ( v ) ] ) ,
202- ) ,
203- } ;
204- } else if ( value . type === "list" ) {
205- let list = value . value ;
206- return {
207- type : "list" ,
208- value : list . map ( ( val ) => strip ( val as PSLiteral < PSValue > ) ) ,
209- } ;
210- } else if ( value . type === "fn" && value . value . type === "platformscript" ) {
211- let { body } = value . value ;
212- return {
213- ...value ,
214- value : {
215- type : "platformscript" ,
216- body : strip ( body ) ,
217- } ,
218- } ;
219- } else if ( value . type === "fncall" ) {
220- return {
221- ...value ,
222- value : strip ( value . value ) as PSFn ,
223- arg : strip ( value . arg ) ,
224- } ;
225- } else {
226- return value ;
227- }
181+ export function parse ( source : string , _filename = "script" ) : PSValue {
182+ return read ( source ) ;
228183}
229184
230185// this is kinda cheesy. We should beef up this check.
@@ -321,44 +276,21 @@ function* bind(
321276 }
322277 return data . list ( result ) ;
323278 } else if ( value . type === "map" ) {
324- let entries = [ ...value . value . entries ( ) ] ;
325- let [ first , ...rest ] = entries ;
326-
327- if ( ! first ) {
328- //TODO: what is this for?
329- return { type : "boolean" , value : false } ;
330- } else {
331- let [ key , value ] = first ;
332- if ( key . type === "ref" ) {
333- let fn = mask . includes ( key . key ) ? key : yield * bind ( key , scope , mask ) ;
334- if ( fn . type !== "fn" && fn . type !== "ref" ) {
335- throw new Error (
336- `'${ key . value } ' is not a function, it is a ${ fn . type } ` ,
337- ) ;
338- }
339- return {
340- type : "fncall" ,
341- value : fn ,
342- arg : yield * bind ( value , scope , mask ) ,
343- rest : { type : "map" , value : new Map ( rest ) } ,
344- } ;
345- } else {
346- let $entries = [ ] as [ PSMapKey , PSValue ] [ ] ;
347- for ( let [ k , v ] of entries ) {
348- $entries . push ( [ k , yield * bind ( v , scope , mask ) ] ) ;
349- }
350- return {
351- type : "map" ,
352- value : new Map ( $entries ) ,
353- } ;
354- }
279+ let $entries = [ ] as [ PSMapKey , PSValue ] [ ] ;
280+ for ( let [ k , v ] of value . value . entries ( ) ) {
281+ $entries . push ( [ k , yield * bind ( v , scope , mask ) ] ) ;
355282 }
283+ return {
284+ type : "map" ,
285+ value : new Map ( $entries ) ,
286+ } ;
356287 } else if ( value . type === "fn" && value . value . type === "platformscript" ) {
357288 let { param, value : { body } } = value ;
358289 return {
359290 ...value ,
360291 value : {
361292 type : "platformscript" ,
293+ head : value . value . head ,
362294 body : yield * bind ( body , scope , mask . concat ( param . name ) ) ,
363295 } ,
364296 } ;
0 commit comments