@@ -11,22 +11,24 @@ export interface LoadOptions {
1111 location : string | URL ;
1212 base ?: string ;
1313 env ?: PSEnv ;
14+ quote ?: boolean ;
1415}
1516
1617export function * load ( options : LoadOptions ) : Operation < PSModule > {
17- let { location, base, env } = options ;
18+ let { location, base, env, quote } = options ;
1819 let url = typeof location === "string" ? new URL ( location , base ) : location ;
1920
2021 let content = yield * read ( url ) ;
2122 let source = parse ( content ) ;
2223
23- return yield * moduleEval ( { source, location : url , env } ) ;
24+ return yield * moduleEval ( { source, location : url , env, quote } ) ;
2425}
2526
2627export interface ModuleEvalOptions {
2728 location : string | URL ;
2829 source : PSValue ;
2930 env ?: PSEnv ;
31+ quote ?: boolean ;
3032}
3133
3234export function * moduleEval ( options : ModuleEvalOptions ) : Operation < PSModule > {
@@ -40,7 +42,7 @@ export function* moduleEval(options: ModuleEvalOptions): Operation<PSModule> {
4042 imports : [ ] ,
4143 } ;
4244
43- if ( source . type !== "map" ) {
45+ if ( source . type !== "map" || options . quote ) {
4446 return mod ;
4547 }
4648
@@ -61,16 +63,36 @@ export function* moduleEval(options: ModuleEvalOptions): Operation<PSModule> {
6163 `imported symbols should be a string, but was ${ names . type } ` ,
6264 ) ;
6365 }
64- if ( loc . type !== "string" ) {
66+ let location : string ;
67+ let quote = false ;
68+ if ( loc . type === "string" ) {
69+ location = loc . value ;
70+ } else if ( loc . type === "map" ) {
71+ let l = lookup ( "location" , loc ) ;
72+ if ( l . type === "nothing" ) {
73+ throw new Error (
74+ `If import specifier is a map, it must have a 'location'` ,
75+ ) ;
76+ } else if ( l . value . type !== "string" ) {
77+ throw new Error (
78+ `'location' attribute of import specifier must be a string, but was '${ l . value . type } '` ,
79+ ) ;
80+ } else {
81+ location = l . value . value ;
82+ }
83+ let quoted = lookup ( "quote" , loc ) ;
84+ quote = quoted . type === "just" && quoted . value . value === true ;
85+ } else {
6586 throw new Error (
66- `import location should be a url string, but was ${ loc . type } ` ,
87+ `import specifier must be either a string or a map , but was ' ${ loc . type } ' ` ,
6788 ) ;
6889 }
6990 let bindings = matchBindings ( names . value ) ;
7091 let dep = yield * load ( {
71- location : loc . value ,
92+ location,
7293 base : url . toString ( ) ,
7394 env,
95+ quote,
7496 } ) ;
7597
7698 mod . imports . push ( {
@@ -82,7 +104,7 @@ export function* moduleEval(options: ModuleEvalOptions): Operation<PSModule> {
82104 let name = binding . alias ?? binding . name ;
83105 let value ;
84106 if ( binding . all ) {
85- value = dep . value ;
107+ value = quote ? data . quote ( dep . value ) : dep . value ;
86108 } else if ( dep . value . type !== "map" ) {
87109 throw new Error (
88110 `tried to import a name from ${ dep . url } , but it is not a 'map'. It is a ${ dep . value . type } ` ,
@@ -94,7 +116,7 @@ export function* moduleEval(options: ModuleEvalOptions): Operation<PSModule> {
94116 `module ${ dep . url } does not have a member named '${ binding . name } '` ,
95117 ) ;
96118 } else {
97- value = result . value ;
119+ value = quote ? data . quote ( result . value ) : result . value ;
98120 }
99121 }
100122 scope . value . set ( data . string ( name ) , value ) ;
@@ -112,7 +134,7 @@ export function* moduleEval(options: ModuleEvalOptions): Operation<PSModule> {
112134 for ( let [ key , value ] of expanded . value . entries ( ) ) {
113135 let evaluated = yield * env . eval ( value , scope ) ;
114136 scope . value . set ( key , evaluated ) ;
115- mod . value . value . set ( key , yield * env . eval ( value , scope ) ) ;
137+ mod . value . value . set ( key , evaluated ) ;
116138 }
117139 }
118140
0 commit comments