@@ -33,26 +33,14 @@ Search for "Embedding the RapydScript compiler in your webpage". There you will
33
33
with instructions for how to use it. Store the file in lib/rapydscript/compiler.js.
34
34
35
35
The in-browser transpiler includes a minimized copy of the run-time function. However, for a program exported
36
- to the user's own web page, the transpiler is not present and a run-time file is need. Here is how to build
37
- the rapydscript-ng runtime library (but see below for an alternative procedure):
38
- 1) Make sure node is installed.
39
- 2) In a new folder, execute "npm install rapydscript-ng".
40
- 3) Create a file named "input.py" in this folder that contains "a=1".
41
- 4) Execute this (modify if not on Windows): node.exe .\node_modules\rapydscript-ng\bin\rapydscript --bare input.py > runtime.js
42
- 5) At the end of the file "runtime.js", delete these lines:
43
- var __name__ = "__main__";
44
-
45
- var a;
46
- a = 1;
47
- 6) Copy the file to lib/rapydscript/runtime.js.
48
- For GlowScript 3.1 runtime.js had the encoding "UCS-2 LE BOM" which the Uglify
49
- machinery could not handle. Using (on Windows) notepad++ the encoding was changed
50
- to "UTF-8" which solved the problem.
51
-
52
- The instructions above for building the two RapydScript files are adequate if it is not necessary to
36
+ to the user's own web page, the transpiler is not present and a run-time file is needed:
37
+ Copy the Github file release/baselib-plain-pretty.js to lib/runtime.js.
38
+
39
+ ===========================================================================================
40
+ The instructions above for obtaining the two RapydScript files are adequate if it is not necessary to
53
41
get the very latest version from the rapydscript-ng repository. If there have been commits to the
54
42
repository that you want, but the key files haven't been updated, replace the instructions with the
55
- following. If on Windows, omit "sudo" from commands.
43
+ following. If on Windows, omit "sudo" from commands, and change "/" to "\" in file names .
56
44
57
45
Build rapydscript-ng from source (from "Installation" section at rapydscript-ng):
58
46
1) Make sure node and git are installed.
@@ -64,25 +52,24 @@ Build rapydscript-ng from source (from "Installation" section at rapydscript-ng)
64
52
3) Execute "sudo bin/rapydscript self --complete --test". This will build files in the "release" folder.
65
53
66
54
Build embedded compiler: (from "Embedding the RapydScript compiler in your webpage" section at rapydscript-ng)
67
- 4) Execute "sudo bin/web-repl-export embedded". This builds the "embedded" (in-browser) compiler.
55
+ 4) Execute "sudo bin/web-repl-export embed". In the (new) folder "embed" the file rapydscript.js is the
56
+ (in-browser) compiler. In December 2021 this did NOT work on Windows and had to be done on a Mac.
68
57
69
58
Move new files to glowscript source:
70
- 5) Copy the file dev/baselib-plain-pretty.js to lib/rapydscript and change the name to runtime.js.
71
- 6) Copy the file embedded/rapydscript.js to lib/rapydscript and change the name to compiler.js.
72
- 7) If not already present, insert these statements at the start of runtime.js (this is a kludge; don't know how to invoke the new compiler):
73
- var ρσ_iterator_symbol = (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") ? Symbol.iterator : "iterator-Symbol-5d0927e5554349048cf0e3762a228256";
74
- var ρσ_kwargs_symbol = (typeof Symbol === "function") ? Symbol("kwargs-object") : "kwargs-object-Symbol-5d0927e5554349048cf0e3762a228256";
75
- var ρσ_cond_temp, ρσ_expr_temp, ρσ_last_exception;
76
- var ρσ_object_counter = 0;
59
+ 5) Copy the file release/baselib-plain-pretty.js to lib/rapydscript runtime.js.
60
+ 6) Copy the file embed/rapydscript.js to lib/rapydscript/compiler.js.
61
+
62
+ However you obtain the two RapydScript-NG files, you need to make the following changes
63
+ in order to enable tests for two vectors being equal or unequal:
77
64
78
65
Make RapydScript-NG handle vec == vec and vec != vec:
79
- In lib/rapydscript/compiler.js, search for "function ρσ_equals" (two places)
66
+ In lib/rapydscript/compiler.js, search for "function ρσ_equals"
80
67
and insert the following string just before "if (a === b)"
81
68
if (a instanceof vec) {\n if (!(b instanceof vec)) return false;\nreturn (a.x === b.x && a.y === b.y && a.z === b.z);\n}\n
82
69
83
70
In lib/rapydscript/compiler.js, search for "function ρσ_not_equals" (two places)
84
71
and insert the following string just before "if (a === b)"
85
- if (a instanceof vec) {\n if (!(b instanceof vec)) return true;\nreturn (a.x !== b.x || a.y !== b.y || a.z !== b.z);\n}\n
72
+ if (a instanceof vec) {\n if (!(b instanceof vec)) return true;\nreturn (a.x !== b.x || a.y !== b.y || a.z !== b.z);\n}\n
86
73
87
74
In lib/rapydscript/runtime.js, search for "function ρσ_equals"
88
75
and insert the following code just before "if (a === b)"
@@ -98,6 +85,17 @@ and insert the following code just before "if (a === b)"
98
85
return (a.x !== b.x || a.y !== b.y || a.z !== b.z);
99
86
}
100
87
88
+ Also, you need to change .pop to .pypop in the two RapydScript-NG files (GScompiler.js converts all occurrences of .pop to .pypop).
89
+ In lib/rapydscript/compiler.js:
90
+ Search for "ans.pop = ρσ_list_pop;" and change ans.pop to ans.pypop in two places.
91
+ Search for "ρσ_set.prototype.pop" and change pop to pypop in two places.
92
+ Search for "ρσ_dict.prototype.pop" and change pop to pypop in two places.
93
+ In lib/rapydscript/runtime.js:
94
+ Search for "ans.pop = ρσ_list_pop" and change ans.pop to ans.pypop.
95
+ Search for "ρσ_set.prototype.pop" and change pop to pypop.
96
+ Search for "ρσ_dict.prototype.pop" and change pop to pypop.
97
+ ===========================================================================================
98
+
101
99
OPERATOR OVERLOADING
102
100
For operator overloading, the source for lib/compiling/papercomp.js is at https://github.com/paperjs/paper.js,
103
101
at src/core/PaperScript.js; compare with papercomp.js, which was modified by Bruce Sherwood for greater speed.
@@ -763,8 +761,9 @@ where compile() was called, in untrusted/run.js.
763
761
program = program . replace ( / \. d e l e t e / g, ".remove" )
764
762
765
763
function pop_replace ( m , p1 , p2 ) {
766
- if ( p2 . length === 0 ) return m
767
- else return '.py' + m . slice ( 1 )
764
+ // if (p2.length === 0) return m // pop()
765
+ // else return '.py'+m.slice(1) // pop(n)
766
+ return '.py' + m . slice ( 1 )
768
767
}
769
768
770
769
const vp_primitives = [ "arrow" , "box" , "compound" , "cone" , "curve" , "cylinder" , "ellipsoid" , "extrusion" ,
@@ -783,12 +782,17 @@ where compile() was called, in untrusted/run.js.
783
782
compile_rapydscript ( program )
784
783
} else { // handle Python imports
785
784
var prog
786
- // if pop(), leave as is to work ok with both lists and sets, but if pop(N), which is only found with lists, use pypop(N)
785
+ // If pop(), leave as is to work ok with both lists and sets (but not dicts),
786
+ // but if pop(N), which is found with lists but not sets, use pypop(N).
787
+ // A difficulty is that pop with Python-like dictionaries has the form pop(attribute),
788
+ // which should return the value of that attribute.
787
789
program = program . replace ( / ( \. p o p \s * \( \s * ) ( [ ^ ) ] * ) / g, pop_replace )
790
+
788
791
program = program . replace ( / \. s o r t \s * \( / g, '.pysort(' ) // Make sort equivalent to pysort (RapydScript python-like sort)
789
792
prog = "def __main__():\n version = " + version + "\n"
790
- // The following turned out to slow all calculations down by about a factor of 5 and so was abandoned:
791
- //prog += " from __python__ import dict_literals, overload_getitem\n" // so that dictionaries behave like Python dictionaries
793
+
794
+ prog += " from __python__ import dict_literals, overload_getitem\n" // so that dictionaries behave like Python dictionaries
795
+
792
796
prog += " window.__GSlang = 'vpython'\n" // WebGLRenderer needs to know at run time what models to create
793
797
// let hasvec = (VPython_names.indexOf('vec') >= 0)
794
798
// let hasvector = (VPython_names.indexOf('vector') >= 0)
@@ -870,7 +874,7 @@ where compile() was called, in untrusted/run.js.
870
874
program = program . replace ( / \* _ G S p o w _ \* / g, '**' ) // restore x**n
871
875
872
876
// handle operator overloading
873
- var start = program . indexOf ( "async function __main__()" )
877
+ start = program . indexOf ( "async function __main__()" )
874
878
var prog = program . slice ( start )
875
879
prog = papercompile ( prog )
876
880
prog = program . slice ( 0 , start ) + prog
@@ -887,7 +891,8 @@ where compile() was called, in untrusted/run.js.
887
891
'shapes' , 'helix' , 'ring' , 'compound' , 'vertex' , 'triangle' , 'quad' , 'label' ,
888
892
'distant_light' , 'local_light' , 'attach_trail' , 'attach_arrow' , 'text' , 'extrusion' ,
889
893
'wtext' , 'winput' , 'radio' , 'checkbox' , 'button' , 'slider' , 'menu' , 'input' , 'js_generator' , 'yield' ,
890
- 'mag' , 'mag2' , 'norm' , 'hat' , 'dot' , 'cross' , 'proj' , 'diff_angle' , 'abs' , 'filter' ,
894
+ 'clear' , 'copy' , 'get' , 'items' , 'keys' , 'values' , 'pypop' , 'popitem' , 'fromkeys' , 'update' , 'setdefault' ,
895
+ 'mag' , 'mag2' , 'norm' , 'hat' , 'dot' , 'cross' , 'proj' , 'diff_angle' , 'abs' , 'filter' , 'set' ,
891
896
'sin' , 'cos' , 'tan' , 'asin' , 'acos' , 'atan' , 'atan2' , 'exp' , 'log' , 'pow' , 'sqrt' ,
892
897
'ceil' , 'floor' , 'sign' , 'round' , 'max' , 'min' , 'random' , "factorial" , "combin" ]
893
898
@@ -946,6 +951,7 @@ where compile() was called, in untrusted/run.js.
946
951
start += m . index + name . length + 1
947
952
continue
948
953
}
954
+
949
955
// If this is a class, delete the call to __init__ (we will insert this call after creating the class instance)
950
956
if ( options . lang == 'vpython' && ! period && classes . indexOf ( name ) >= 0 ) {
951
957
start += m . index + name . length + 1
@@ -991,6 +997,10 @@ where compile() was called, in untrusted/run.js.
991
997
}
992
998
993
999
let pstart = ptr + 1 // start of ....f()
1000
+ if ( prog . slice ( pstart , pstart + 11 ) == 's.jsset.add' ) { // this is a set
1001
+ start += m . index + name . length + 1
1002
+ continue
1003
+ }
994
1004
let prefix = ''
995
1005
if ( period ) {
996
1006
// paths and shapes are lists which need to be converted to RapydScript lists to have methods such as insert
@@ -1067,7 +1077,8 @@ where compile() was called, in untrusted/run.js.
1067
1077
let no_await2 = [ 'remove' , 'select' , 'append_to_title' , 'append_to_caption' , 'bind' , 'unbind' , 'call' , 'append' ,
1068
1078
'rgb_to_hsv' , 'hsv_to_rgb' , 'mag' , 'mag2' , 'norm' , 'hat' , 'rotate' , 'random' , 'pow' , 'equals' ,
1069
1079
'format' , 'trigger' , 'follow' , 'defineProperties' , 'textures' , 'bumpmaps' , 'slice' , 'plot' ,
1070
- 'pop' , 'pypop' , 'insert' , 'find' , 'extend' , 'copy' , 'count' , 'reverse' , 'pysort' ,
1080
+ 'pypop' , 'insert' , 'find' , 'extend' , 'copy' , 'count' , 'reverse' , 'pysort' , 'set' ,
1081
+ 'clear' , 'copy' , 'get' , 'items' , 'keys' , 'values' , 'popitem' , 'fromkeys' , 'update' , 'setdefault' ,
1071
1082
'npoints' , 'unshift' , 'splice' , 'modify' , 'clear' , 'shift' , 'point' , 'slice' ]
1072
1083
1073
1084
// If not a user function, nor pause/waitfor/rate/sleep/read_local_file/get_library,
@@ -1177,10 +1188,11 @@ where compile() was called, in untrusted/run.js.
1177
1188
1178
1189
// Delete the string inserts of function-like elements of strings:
1179
1190
program = program . replace ( new RegExp ( string_insert , 'g' ) , '(' )
1191
+
1192
+ let s = "scene = canvas();\n"
1193
+ let sc = program . indexOf ( s ) + s . length
1180
1194
1181
1195
if ( loadfonts ) { // if text object is in user program
1182
- let s = "scene = canvas();\n"
1183
- let sc = program . indexOf ( s ) + s . length
1184
1196
s = " fontloading();\n await waitforfonts();\n" // wait for font files
1185
1197
program = program . slice ( 0 , sc ) + s + program . slice ( sc , program . length )
1186
1198
}
@@ -1189,8 +1201,6 @@ where compile() was called, in untrusted/run.js.
1189
1201
// and it looks like Chrome will also start doing this. So starting with version 3.2, we insert the
1190
1202
// input function into the user's program:
1191
1203
if ( program . indexOf ( 'input' ) >= 0 ) { // if user code invokes input(), insert the function:
1192
- let s = "scene = canvas();\n"
1193
- let sc = program . indexOf ( s ) + s . length
1194
1204
s = "\n function input(arg) {\n"
1195
1205
s += " arg = arg || {}\n"
1196
1206
s += " if (arg.prompt !== undefined && arg.prompt != '') return prompt(arg.prompt)\n"
@@ -1200,6 +1210,9 @@ where compile() was called, in untrusted/run.js.
1200
1210
program = program . slice ( 0 , sc ) + s + program . slice ( sc , program . length )
1201
1211
}
1202
1212
1213
+ // s = " ρσ_list_decorate.prototype.pop = function(arg) {return this.pypop(arg)}\n"
1214
+ // program = program.slice(0,sc)+s+program.slice(sc,program.length)
1215
+
1203
1216
// var p = program.split('\n')
1204
1217
// for (var i=0; i<p.length; i++) console.log(i, p[i])
1205
1218
// console.log('fcts', fcts)
@@ -1208,8 +1221,8 @@ where compile() was called, in untrusted/run.js.
1208
1221
// console.log('classinstances', classinstances)
1209
1222
// console.log('classmethods', classmethods)
1210
1223
// console.log('============================================================================')
1211
- // var i = program.search('async function __main__')
1212
1224
// var i = program.search('"2";')
1225
+ // var i = program.search('async function __main__')
1213
1226
// console.log(program.slice(i))
1214
1227
// console.log(program)
1215
1228
return program
0 commit comments