bare-script 4.2.6__tar.gz → 4.2.8__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. {bare_script-4.2.6/src/bare_script.egg-info → bare_script-4.2.8}/PKG-INFO +6 -6
  2. {bare_script-4.2.6 → bare_script-4.2.8}/README.md +5 -5
  3. {bare_script-4.2.6 → bare_script-4.2.8}/setup.cfg +1 -1
  4. bare_script-4.2.8/src/bare_script/include/baredoc.bare +383 -0
  5. {bare_script-4.2.6 → bare_script-4.2.8}/src/bare_script/library.py +14 -0
  6. {bare_script-4.2.6 → bare_script-4.2.8}/src/bare_script/runtime.py +104 -1
  7. {bare_script-4.2.6 → bare_script-4.2.8/src/bare_script.egg-info}/PKG-INFO +6 -6
  8. bare_script-4.2.6/src/bare_script/include/baredoc.bare +0 -340
  9. {bare_script-4.2.6 → bare_script-4.2.8}/LICENSE +0 -0
  10. {bare_script-4.2.6 → bare_script-4.2.8}/pyproject.toml +0 -0
  11. {bare_script-4.2.6 → bare_script-4.2.8}/setup.py +0 -0
  12. {bare_script-4.2.6 → bare_script-4.2.8}/src/bare_script/__init__.py +0 -0
  13. {bare_script-4.2.6 → bare_script-4.2.8}/src/bare_script/__main__.py +0 -0
  14. {bare_script-4.2.6 → bare_script-4.2.8}/src/bare_script/bare.py +0 -0
  15. {bare_script-4.2.6 → bare_script-4.2.8}/src/bare_script/include/__init__.py +0 -0
  16. {bare_script-4.2.6 → bare_script-4.2.8}/src/bare_script/include/args.bare +0 -0
  17. {bare_script-4.2.6 → bare_script-4.2.8}/src/bare_script/include/baredocCLI.bare +0 -0
  18. {bare_script-4.2.6 → bare_script-4.2.8}/src/bare_script/include/data.bare +0 -0
  19. {bare_script-4.2.6 → bare_script-4.2.8}/src/bare_script/include/dataLineChart.bare +0 -0
  20. {bare_script-4.2.6 → bare_script-4.2.8}/src/bare_script/include/dataTable.bare +0 -0
  21. {bare_script-4.2.6 → bare_script-4.2.8}/src/bare_script/include/dataUtil.bare +0 -0
  22. {bare_script-4.2.6 → bare_script-4.2.8}/src/bare_script/include/diff.bare +0 -0
  23. {bare_script-4.2.6 → bare_script-4.2.8}/src/bare_script/include/draw.bare +0 -0
  24. {bare_script-4.2.6 → bare_script-4.2.8}/src/bare_script/include/elementModel.bare +0 -0
  25. {bare_script-4.2.6 → bare_script-4.2.8}/src/bare_script/include/forms.bare +0 -0
  26. {bare_script-4.2.6 → bare_script-4.2.8}/src/bare_script/include/markdown.bare +0 -0
  27. {bare_script-4.2.6 → bare_script-4.2.8}/src/bare_script/include/markdownElements.bare +0 -0
  28. {bare_script-4.2.6 → bare_script-4.2.8}/src/bare_script/include/markdownHighlight.bare +0 -0
  29. {bare_script-4.2.6 → bare_script-4.2.8}/src/bare_script/include/markdownParser.bare +0 -0
  30. {bare_script-4.2.6 → bare_script-4.2.8}/src/bare_script/include/markdownUp.bare +0 -0
  31. {bare_script-4.2.6 → bare_script-4.2.8}/src/bare_script/include/pager.bare +0 -0
  32. {bare_script-4.2.6 → bare_script-4.2.8}/src/bare_script/include/qrcode.bare +0 -0
  33. {bare_script-4.2.6 → bare_script-4.2.8}/src/bare_script/include/schemaDoc.bare +0 -0
  34. {bare_script-4.2.6 → bare_script-4.2.8}/src/bare_script/include/unittest.bare +0 -0
  35. {bare_script-4.2.6 → bare_script-4.2.8}/src/bare_script/include/unittestMock.bare +0 -0
  36. {bare_script-4.2.6 → bare_script-4.2.8}/src/bare_script/model.py +0 -0
  37. {bare_script-4.2.6 → bare_script-4.2.8}/src/bare_script/options.py +0 -0
  38. {bare_script-4.2.6 → bare_script-4.2.8}/src/bare_script/parser.py +0 -0
  39. {bare_script-4.2.6 → bare_script-4.2.8}/src/bare_script/runtime_c.c +0 -0
  40. {bare_script-4.2.6 → bare_script-4.2.8}/src/bare_script/value.py +0 -0
  41. {bare_script-4.2.6 → bare_script-4.2.8}/src/bare_script.egg-info/SOURCES.txt +0 -0
  42. {bare_script-4.2.6 → bare_script-4.2.8}/src/bare_script.egg-info/dependency_links.txt +0 -0
  43. {bare_script-4.2.6 → bare_script-4.2.8}/src/bare_script.egg-info/entry_points.txt +0 -0
  44. {bare_script-4.2.6 → bare_script-4.2.8}/src/bare_script.egg-info/requires.txt +0 -0
  45. {bare_script-4.2.6 → bare_script-4.2.8}/src/bare_script.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bare-script
3
- Version: 4.2.6
3
+ Version: 4.2.8
4
4
  Summary: bare-script
5
5
  Home-page: https://github.com/craigahobbs/bare-script
6
6
  Author: Craig A. Hobbs
@@ -104,11 +104,11 @@ from bare_script import execute_script, fetch_http, parse_script
104
104
 
105
105
  # Parse the script
106
106
  script = parse_script('''\
107
- # Fetch the BareScript library documentation JSON
108
- docs = jsonParse(systemFetch('https://craigahobbs.github.io/bare-script-py/library/library.json'))
107
+ # Fetch the BareScript builtin library documentation JSON
108
+ docs = jsonParse(systemFetch('https://craigahobbs.github.io/bare-script-py/library/library-builtin.json'))
109
109
 
110
- # Return the number of library functions
111
- return 'The BareScript Library has ' + arrayLength(objectGet(docs, 'functions')) + ' functions'
110
+ # Return the number of builtin functions
111
+ return 'The BareScript Library has ' + arrayLength(objectGet(docs, 'functions')) + ' builtin functions'
112
112
  ''')
113
113
 
114
114
  # Execute the script
@@ -118,7 +118,7 @@ print(execute_script(script, {'fetchFn': fetch_http}))
118
118
  This outputs:
119
119
 
120
120
  ```
121
- The BareScript Library has 209 functions
121
+ The BareScript Library has 108 builtin functions
122
122
  ```
123
123
 
124
124
 
@@ -79,11 +79,11 @@ from bare_script import execute_script, fetch_http, parse_script
79
79
 
80
80
  # Parse the script
81
81
  script = parse_script('''\
82
- # Fetch the BareScript library documentation JSON
83
- docs = jsonParse(systemFetch('https://craigahobbs.github.io/bare-script-py/library/library.json'))
82
+ # Fetch the BareScript builtin library documentation JSON
83
+ docs = jsonParse(systemFetch('https://craigahobbs.github.io/bare-script-py/library/library-builtin.json'))
84
84
 
85
- # Return the number of library functions
86
- return 'The BareScript Library has ' + arrayLength(objectGet(docs, 'functions')) + ' functions'
85
+ # Return the number of builtin functions
86
+ return 'The BareScript Library has ' + arrayLength(objectGet(docs, 'functions')) + ' builtin functions'
87
87
  ''')
88
88
 
89
89
  # Execute the script
@@ -93,7 +93,7 @@ print(execute_script(script, {'fetchFn': fetch_http}))
93
93
  This outputs:
94
94
 
95
95
  ```
96
- The BareScript Library has 209 functions
96
+ The BareScript Library has 108 builtin functions
97
97
  ```
98
98
 
99
99
 
@@ -1,6 +1,6 @@
1
1
  [metadata]
2
2
  name = bare-script
3
- version = 4.2.6
3
+ version = 4.2.8
4
4
  url = https://github.com/craigahobbs/bare-script
5
5
  author = Craig A. Hobbs
6
6
  author_email = craigahobbs@gmail.com
@@ -0,0 +1,383 @@
1
+ # Licensed under the MIT License
2
+ # https://github.com/craigahobbs/bare-script/blob/main/LICENSE
3
+
4
+ include <args.bare>
5
+ include <markdown.bare>
6
+ include <dataUtil.bare>
7
+ include <dataTable.bare>
8
+ include <schemaDoc.bare>
9
+
10
+
11
+ # $function: baredocMain
12
+ # $group: baredoc.bare
13
+ # $doc: The BareScript library documentation application main entry point
14
+ # $arg config: The [documentation configuration](model.html#var.vName='BaredocConfig') object or its JSON resource URL
15
+ async function baredocMain(config):
16
+ # Parse arguments
17
+ args = argsParse(baredocArguments)
18
+ group = objectGet(args, 'group')
19
+ name = objectGet(args, 'name')
20
+ single = objectGet(args, 'single')
21
+
22
+ # Render the documentation model page?
23
+ if objectGet(args, 'doc'):
24
+ documentSetTitle('Library')
25
+ markdownPrint(schemaDocMarkdown(baredocTypes, 'BaredocLibrary'))
26
+ return
27
+ endif
28
+
29
+ # Resolve and validate the configuration
30
+ if systemType(config) == 'string':
31
+ config = jsonParse(systemFetch(config))
32
+ endif
33
+ config = schemaValidate(baredocTypes, 'BaredocConfig', config)
34
+ if config == null:
35
+ markdownPrint('**Error:** Invalid baredoc configuration')
36
+ return
37
+ endif
38
+ sections = objectGet(config, 'sections')
39
+
40
+ # Fetch and validate the section library documentation resources
41
+ sectionURLs = []
42
+ for section in sections:
43
+ arrayPush(sectionURLs, objectGet(section, 'url'))
44
+ endfor
45
+ sectionJSONs = systemFetch(sectionURLs)
46
+
47
+ # Group each section's functions by name, with the config content and description
48
+ groups = {}
49
+ sectionGroups = []
50
+ for section, ixSection in sections:
51
+ sectionJSON = arrayGet(sectionJSONs, ixSection)
52
+ libraryPart = if(sectionJSON != null, jsonParse(sectionJSON))
53
+ libraryPart = if(libraryPart != null, schemaValidate(baredocTypes, 'BaredocLibrary', libraryPart))
54
+ if libraryPart == null:
55
+ markdownPrint( \
56
+ '**Error:** Failed to fetch library documentation resource "' + \
57
+ markdownEscape(objectGet(section, 'url')) + '"' \
58
+ )
59
+ return
60
+ endif
61
+
62
+ # Group the section's functions
63
+ sectionGroupSet = {}
64
+ for function_ in objectGet(libraryPart, 'functions'):
65
+ groupName = objectGet(function_, 'group')
66
+ groupEntry = objectGet(groups, groupName)
67
+ if groupEntry == null:
68
+ groupEntry = {'functions': []}
69
+ objectSet(groups, groupName, groupEntry)
70
+ endif
71
+ arrayPush(objectGet(groupEntry, 'functions'), function_)
72
+ objectSet(sectionGroupSet, groupName, true)
73
+ endfor
74
+ arrayPush(sectionGroups, {'title': objectGet(section, 'title'), 'groupNames': arraySort(objectKeys(sectionGroupSet))})
75
+
76
+ # Attach the section's group content and description from the config
77
+ for group_ in objectGet(section, 'groups', []):
78
+ groupEntry = objectGet(groups, objectGet(group_, 'name'))
79
+ if groupEntry != null:
80
+ objectSet(groupEntry, 'content', objectGet(group_, 'content'))
81
+ objectSet(groupEntry, 'description', objectGet(group_, 'description'))
82
+ endif
83
+ endfor
84
+ endfor
85
+
86
+ # Sort each group's functions by name
87
+ for groupName in objectKeys(groups):
88
+ arraySort(objectGet(objectGet(groups, groupName), 'functions'), baredocFunctionCompare)
89
+ endfor
90
+
91
+ # Function requested by name? Redirect to its group page anchor
92
+ if name != null:
93
+ for groupName in objectKeys(groups):
94
+ for function_ in objectGet(objectGet(groups, groupName), 'functions'):
95
+ if objectGet(function_, 'name') == name:
96
+ windowSetLocation(argsURL(baredocArguments, {'group': groupName, 'name': null}, false, name))
97
+ return
98
+ endif
99
+ endfor
100
+ endfor
101
+ markdownPrint('', '**Error:** Unknown function "' + markdownEscape(name) + '"')
102
+ return
103
+ endif
104
+
105
+ # Render the requested page
106
+ if group != null:
107
+ baredocGroupPage(config, args, groups, group)
108
+ elif single:
109
+ baredocSinglePage(config, args, sectionGroups, groups)
110
+ else:
111
+ baredocIndexPage(config, args, sectionGroups, groups)
112
+ endif
113
+ endfunction
114
+
115
+
116
+ # The BareScript library documentation application arguments
117
+ baredocArguments = argsValidate([ \
118
+ {'name': 'doc', 'type': 'bool', 'default': false}, \
119
+ {'name': 'group'}, \
120
+ {'name': 'name'}, \
121
+ {'name': 'publish', 'type': 'bool', 'default': false}, \
122
+ {'name': 'single', 'type': 'bool', 'default': false} \
123
+ ])
124
+
125
+
126
+ # Helper to compare library function objects by name
127
+ function baredocFunctionCompare(f1, f2):
128
+ f1Name = objectGet(f1, 'name')
129
+ f2Name = objectGet(f2, 'name')
130
+ return if(f1Name < f2Name, -1, if(f1Name == f2Name, 0, 1))
131
+ endfunction
132
+
133
+
134
+ # Helper to render the title and top-level content
135
+ async function baredocPageHeader(config):
136
+ title = objectGet(config, 'title')
137
+ documentSetTitle(title)
138
+ markdownPrint('# ' + markdownEscape(title))
139
+ topContent = objectGet(config, 'content')
140
+ if topContent != null:
141
+ topText = systemFetch(topContent)
142
+ markdownPrint('', if(topText != null, topText, '**Error:** Failed to load "' + markdownEscape(topContent) + '"'))
143
+ endif
144
+ endfunction
145
+
146
+
147
+ # Render the section group index tables (single uses in-page anchors, multi-page uses group pages)
148
+ function baredocGroupTable(sectionGroups, groups, single):
149
+ for section in sectionGroups:
150
+ markdownPrint('', '## ' + markdownEscape(objectGet(section, 'title')), '')
151
+ markdownPrint('| | |', '| --- | --- |')
152
+ for groupName in objectGet(section, 'groupNames'):
153
+ groupLink = if(single, \
154
+ argsLink(baredocArguments, groupName, null, false, groupName), \
155
+ argsLink(baredocArguments, groupName, {'group': groupName}, false, argsTopHeaderId))
156
+ description = objectGet(objectGet(groups, groupName), 'description')
157
+ markdownPrint('| ' + groupLink + ' | ' + if(description != null, description, '') + ' |')
158
+ endfor
159
+ endfor
160
+ endfunction
161
+
162
+
163
+ # Render a library documentation index page
164
+ async function baredocIndexPage(config, args, sectionGroups, groups):
165
+ # Render the title and top-level content
166
+ baredocPageHeader(config)
167
+
168
+ # Render the single page toggle
169
+ if !objectGet(args, 'publish'):
170
+ markdownPrint('', argsLink(baredocArguments, 'Single Page', {'single': true}))
171
+ endif
172
+
173
+ # Render the section group index tables
174
+ baredocGroupTable(sectionGroups, groups, false)
175
+ endfunction
176
+
177
+
178
+ # Render the single-page library documentation
179
+ async function baredocSinglePage(config, args, sectionGroups, groups):
180
+ # Render the title and top-level content
181
+ baredocPageHeader(config)
182
+
183
+ # Render the multi page toggle
184
+ if !objectGet(args, 'publish'):
185
+ markdownPrint('', argsLink(baredocArguments, 'Multi Page', {'single': false}))
186
+ endif
187
+
188
+ # Render the section group index tables
189
+ baredocGroupTable(sectionGroups, groups, true)
190
+
191
+ # Batch-fetch all group content, keyed by group name
192
+ contentNames = []
193
+ urls = []
194
+ for groupName in objectKeys(groups):
195
+ url = objectGet(objectGet(groups, groupName), 'content')
196
+ if url != null:
197
+ arrayPush(contentNames, groupName)
198
+ arrayPush(urls, url)
199
+ endif
200
+ endfor
201
+ texts = systemFetch(urls)
202
+ groupContent = {}
203
+ for groupName, ixName in contentNames:
204
+ text = arrayGet(texts, ixName)
205
+ objectSet(groupContent, groupName, if(text != null, text, '**Error:** Failed to load "' + markdownEscape(arrayGet(urls, ixName)) + '"'))
206
+ endfor
207
+
208
+ # Render each group, separated by a horizontal rule
209
+ for section in sectionGroups:
210
+ for groupName in objectGet(section, 'groupNames'):
211
+ markdownPrint('', '---', '')
212
+ baredocGroup(args, objectGet(groupContent, groupName), groups, groupName, '##')
213
+ endfor
214
+ endfor
215
+ endfunction
216
+
217
+
218
+ # Render a library documentation group page
219
+ async function baredocGroupPage(config, args, groups, groupName):
220
+ title = objectGet(config, 'title')
221
+
222
+ # Set the document title
223
+ documentSetTitle(title + ' - ' + groupName)
224
+
225
+ # Group exist?
226
+ if !objectHas(groups, groupName):
227
+ markdownPrint('', '**Error:** Unknown group "' + markdownEscape(groupName) + '"')
228
+ return
229
+ endif
230
+
231
+ # Fetch the group content
232
+ url = objectGet(objectGet(groups, groupName), 'content')
233
+ groupContent = null
234
+ if url != null:
235
+ text = systemFetch(url)
236
+ groupContent = if(text != null, text, '**Error:** Failed to load "' + markdownEscape(url) + '"')
237
+ endif
238
+
239
+ # Render the index link and the group
240
+ markdownPrint(argsLink(baredocArguments, 'Index', {'group': null}), '')
241
+ baredocGroup(args, groupContent, groups, groupName, '#')
242
+ endfunction
243
+
244
+
245
+ # Render a documentation group's content, function index, and function documentation
246
+ function baredocGroup(args, groupContent, groups, groupName, baseHeader):
247
+ publish = objectGet(args, 'publish')
248
+ single = objectGet(args, 'single')
249
+ groupEntry = objectGet(groups, groupName)
250
+
251
+ # Render the group header
252
+ markdownPrint(baseHeader + ' ' + markdownEscape(groupName))
253
+ if single && !publish:
254
+ markdownPrint('', argsLink(baredocArguments, 'Back to top', null, false, argsTopHeaderId))
255
+ endif
256
+
257
+ # Render the group content (the fetched content or load error, else the description)
258
+ content = if(groupContent != null, groupContent, objectGet(groupEntry, 'description'))
259
+ if content != null:
260
+ markdownPrint('', content)
261
+ endif
262
+
263
+ # Render the group function index
264
+ groupFunctions = objectGet(groupEntry, 'functions')
265
+ markdownPrint('', baseHeader + '# Function Index', '')
266
+ for function_ in groupFunctions:
267
+ functionName = objectGet(function_, 'name')
268
+ markdownPrint('- ' + argsLink(baredocArguments, functionName, null, false, functionName))
269
+ endfor
270
+
271
+ # Render the group function documentation
272
+ for function_ in groupFunctions:
273
+ # Render the function header
274
+ markdownPrint( \
275
+ '', \
276
+ '---', \
277
+ '', \
278
+ baseHeader + '# ' + markdownEscape(objectGet(function_, 'name')), \
279
+ '', \
280
+ objectGet(function_, 'doc') \
281
+ )
282
+
283
+ # Render the functions's argument documentation
284
+ markdownPrint('', baseHeader + '## Arguments')
285
+ arguments = objectGet(function_, 'args')
286
+ if arguments != null:
287
+ for argument in arguments:
288
+ markdownPrint('', '**' + markdownEscape(objectGet(argument, 'name')) + ' -**', objectGet(argument, 'doc'))
289
+ endfor
290
+ else:
291
+ markdownPrint('', 'None')
292
+ endif
293
+
294
+ # Render the function's return documentation
295
+ markdownPrint('', baseHeader + '## Returns')
296
+ returnDoc = objectGet(function_, 'return')
297
+ markdownPrint('', if(returnDoc != null, returnDoc, 'Nothing'))
298
+ endfor
299
+ endfunction
300
+
301
+
302
+ # The library documentation schema
303
+ baredocTypes = schemaParse( \
304
+ 'group "baredoc.bare"', \
305
+ '', \
306
+ '', \
307
+ '# The baredoc documentation application configuration', \
308
+ 'struct BaredocConfig', \
309
+ '', \
310
+ ' # The documentation title', \
311
+ ' string title', \
312
+ '', \
313
+ ' # The optional top-level Markdown content resource URL', \
314
+ ' optional string content', \
315
+ '', \
316
+ ' # The documentation sections', \
317
+ ' BaredocSection[] sections', \
318
+ '', \
319
+ '', \
320
+ '# A documentation section', \
321
+ 'struct BaredocSection', \
322
+ '', \
323
+ ' # The section title', \
324
+ ' string title', \
325
+ '', \
326
+ " # The section's library documentation JSON resource URL", \
327
+ ' string url', \
328
+ '', \
329
+ ' # Optional content and descriptions for the groups (groups are defined by the library functions)', \
330
+ ' optional BaredocGroup[] groups', \
331
+ '', \
332
+ '', \
333
+ "# A library function group's content and description (the group is defined by the library functions)", \
334
+ 'struct BaredocGroup', \
335
+ '', \
336
+ ' # The group name (matches a library function group)', \
337
+ ' string name', \
338
+ '', \
339
+ ' # The optional group Markdown content resource URL (defaults to the description)', \
340
+ ' optional string content', \
341
+ '', \
342
+ ' # The optional brief group description Markdown for the index page', \
343
+ ' optional string description', \
344
+ '', \
345
+ '', \
346
+ '# A library documentation model', \
347
+ 'struct BaredocLibrary', \
348
+ '', \
349
+ ' # The library functions', \
350
+ ' BaredocFunction[] functions', \
351
+ '', \
352
+ '', \
353
+ '# A library function', \
354
+ 'struct BaredocFunction', \
355
+ '', \
356
+ ' # The function name', \
357
+ ' string name', \
358
+ '', \
359
+ ' # The function group (e.g. "Math")', \
360
+ ' string group', \
361
+ '', \
362
+ " # The function's documentation Markdown lines", \
363
+ ' string[] doc', \
364
+ '', \
365
+ ' # The function arguments', \
366
+ ' optional BaredocFunctionArgument[] args', \
367
+ '', \
368
+ " # The function return's documentation Markdown lines", \
369
+ ' optional string[] return', \
370
+ '', \
371
+ ' # If true, ignore the function', \
372
+ ' optional bool ignore', \
373
+ '', \
374
+ '', \
375
+ '# A function argument', \
376
+ 'struct BaredocFunctionArgument', \
377
+ '', \
378
+ ' # The argument name', \
379
+ ' string name', \
380
+ '', \
381
+ " # The argument's documentation Markdown lines", \
382
+ ' string[] doc' \
383
+ )
@@ -2208,3 +2208,17 @@ EXPRESSION_FUNCTIONS = dict(
2208
2208
  (expr_fn_name, SCRIPT_FUNCTIONS[script_fn_name])
2209
2209
  for expr_fn_name, script_fn_name in EXPRESSION_FUNCTION_MAP.items()
2210
2210
  )
2211
+
2212
+
2213
+ # Library functions with an inline "intrinsic" fast path in the runtime call dispatch. Membership is by
2214
+ # function-object identity, so any override (a user function, an options global, or an unittestMock
2215
+ # systemGlobalSet) is a different object that misses the set and takes the normal call path. Kept small
2216
+ # on purpose: these hot, validation-heavy accessors measured as ~all of the include-test speedup.
2217
+ # Defined here, next to SCRIPT_FUNCTIONS, mirroring the JavaScript implementation.
2218
+ INTRINSICS = frozenset((
2219
+ SCRIPT_FUNCTIONS['arrayGet'],
2220
+ SCRIPT_FUNCTIONS['arrayPush'],
2221
+ SCRIPT_FUNCTIONS['arraySet'],
2222
+ SCRIPT_FUNCTIONS['objectGet'],
2223
+ SCRIPT_FUNCTIONS['objectSet'],
2224
+ ))
@@ -8,7 +8,7 @@ The BareScript runtime
8
8
  import datetime
9
9
  import functools
10
10
 
11
- from .library import EXPRESSION_FUNCTIONS, SCRIPT_FUNCTIONS
11
+ from .library import EXPRESSION_FUNCTIONS, INTRINSICS, SCRIPT_FUNCTIONS
12
12
  from .model import lint_script
13
13
  from .options import url_file_relative
14
14
  from .parser import parse_script
@@ -315,6 +315,109 @@ def evaluate_expression(expr, options=None, locals_=None, builtins=True, script=
315
315
  if func_value is not None:
316
316
  # Call the function
317
317
  try:
318
+ # Intrinsic fast path: run the body inline, skipping value_args_validate and the
319
+ # call frame. Bad arguments raise ValueArgsError, handled by the except below exactly
320
+ # as the normal call would; a call reaching one of these under a different name (an
321
+ # alias) matches no branch and falls through to the normal call.
322
+ if func_value in INTRINSICS:
323
+ func_args_length = len(func_args)
324
+ if func_name == 'arrayGet':
325
+ if func_args_length < 1:
326
+ raise ValueArgsError('array', None)
327
+ array_value = func_args[0]
328
+ array_type = type(array_value)
329
+ if array_type is not list:
330
+ raise ValueArgsError('array', array_value)
331
+ if func_args_length < 2:
332
+ raise ValueArgsError('index', None)
333
+ index_value = func_args[1]
334
+ index_type = type(index_value)
335
+ if index_type is float:
336
+ if index_value < 0 or not index_value.is_integer():
337
+ raise ValueArgsError('index', index_value)
338
+ index_value = int(index_value)
339
+ elif index_type is int:
340
+ if index_value < 0:
341
+ raise ValueArgsError('index', index_value)
342
+ else:
343
+ raise ValueArgsError('index', index_value)
344
+ if func_args_length > 2:
345
+ raise ValueArgsError(None, func_args_length)
346
+ if index_value >= len(array_value):
347
+ raise ValueArgsError('index', index_value)
348
+ return array_value[index_value]
349
+ if func_name == 'arrayPush':
350
+ if func_args_length < 1:
351
+ raise ValueArgsError('array', None)
352
+ array_value = func_args[0]
353
+ array_type = type(array_value)
354
+ if array_type is not list:
355
+ raise ValueArgsError('array', array_value)
356
+ array_value.extend(func_args[1:])
357
+ return array_value
358
+ if func_name == 'arraySet':
359
+ if func_args_length < 1:
360
+ raise ValueArgsError('array', None)
361
+ array_value = func_args[0]
362
+ array_type = type(array_value)
363
+ if array_type is not list:
364
+ raise ValueArgsError('array', array_value)
365
+ if func_args_length < 2:
366
+ raise ValueArgsError('index', None)
367
+ index_value = func_args[1]
368
+ index_type = type(index_value)
369
+ if index_type is float:
370
+ if index_value < 0 or not index_value.is_integer():
371
+ raise ValueArgsError('index', index_value)
372
+ index_value = int(index_value)
373
+ elif index_type is int:
374
+ if index_value < 0:
375
+ raise ValueArgsError('index', index_value)
376
+ else:
377
+ raise ValueArgsError('index', index_value)
378
+ if func_args_length > 3:
379
+ raise ValueArgsError(None, func_args_length)
380
+ if index_value >= len(array_value):
381
+ raise ValueArgsError('index', index_value)
382
+ set_value = func_args[2] if func_args_length >= 3 else None
383
+ array_value[index_value] = set_value
384
+ return set_value
385
+ if func_name == 'objectGet':
386
+ default_value = func_args[2] if func_args_length >= 3 else None
387
+ if func_args_length < 1:
388
+ raise ValueArgsError('object', None, default_value)
389
+ object_value = func_args[0]
390
+ object_type = type(object_value)
391
+ if object_type is not dict:
392
+ raise ValueArgsError('object', object_value, default_value)
393
+ if func_args_length < 2:
394
+ raise ValueArgsError('key', None, default_value)
395
+ key_value = func_args[1]
396
+ key_type = type(key_value)
397
+ if key_type is not str:
398
+ raise ValueArgsError('key', key_value, default_value)
399
+ if func_args_length > 3:
400
+ raise ValueArgsError(None, func_args_length, default_value)
401
+ return object_value.get(key_value, default_value)
402
+ if func_name == 'objectSet':
403
+ if func_args_length < 1:
404
+ raise ValueArgsError('object', None)
405
+ object_value = func_args[0]
406
+ object_type = type(object_value)
407
+ if object_type is not dict:
408
+ raise ValueArgsError('object', object_value)
409
+ if func_args_length < 2:
410
+ raise ValueArgsError('key', None)
411
+ key_value = func_args[1]
412
+ key_type = type(key_value)
413
+ if key_type is not str:
414
+ raise ValueArgsError('key', key_value)
415
+ if func_args_length > 3:
416
+ raise ValueArgsError(None, func_args_length)
417
+ set_value = func_args[2] if func_args_length >= 3 else None
418
+ object_value[key_value] = set_value
419
+ return set_value
420
+
318
421
  return func_value(func_args, options)
319
422
  except BareScriptRuntimeError:
320
423
  raise
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bare-script
3
- Version: 4.2.6
3
+ Version: 4.2.8
4
4
  Summary: bare-script
5
5
  Home-page: https://github.com/craigahobbs/bare-script
6
6
  Author: Craig A. Hobbs
@@ -104,11 +104,11 @@ from bare_script import execute_script, fetch_http, parse_script
104
104
 
105
105
  # Parse the script
106
106
  script = parse_script('''\
107
- # Fetch the BareScript library documentation JSON
108
- docs = jsonParse(systemFetch('https://craigahobbs.github.io/bare-script-py/library/library.json'))
107
+ # Fetch the BareScript builtin library documentation JSON
108
+ docs = jsonParse(systemFetch('https://craigahobbs.github.io/bare-script-py/library/library-builtin.json'))
109
109
 
110
- # Return the number of library functions
111
- return 'The BareScript Library has ' + arrayLength(objectGet(docs, 'functions')) + ' functions'
110
+ # Return the number of builtin functions
111
+ return 'The BareScript Library has ' + arrayLength(objectGet(docs, 'functions')) + ' builtin functions'
112
112
  ''')
113
113
 
114
114
  # Execute the script
@@ -118,7 +118,7 @@ print(execute_script(script, {'fetchFn': fetch_http}))
118
118
  This outputs:
119
119
 
120
120
  ```
121
- The BareScript Library has 209 functions
121
+ The BareScript Library has 108 builtin functions
122
122
  ```
123
123
 
124
124
 
@@ -1,340 +0,0 @@
1
- # Licensed under the MIT License
2
- # https://github.com/craigahobbs/bare-script/blob/main/LICENSE
3
-
4
- include <args.bare>
5
- include <markdown.bare>
6
- include <dataUtil.bare>
7
- include <dataTable.bare>
8
- include <schemaDoc.bare>
9
-
10
-
11
- # $function: baredocMain
12
- # $group: baredoc.bare
13
- # $doc: The BareScript library documentation application main entry point
14
- # $arg url: The library documentation JSON resource URL
15
- # $arg title: The library title
16
- # $arg menuLinks: Optional array of text/URL menu link tuples
17
- # $arg groupURLs: Optional map of group name to group Markdown content URL ('' is index) or JSON resource URL
18
- async function baredocMain(url, title, menuLinks, groupURLs):
19
- # Parse arguments
20
- args = argsParse(baredocArguments)
21
- group = objectGet(args, 'group')
22
- name = objectGet(args, 'name')
23
- single = objectGet(args, 'single')
24
- url = objectGet(args, 'url', url)
25
-
26
- # Render library JSON documentation page?
27
- if objectGet(args, 'doc'):
28
- documentSetTitle('Library')
29
- markdownPrint(schemaDocMarkdown(baredocTypes, 'BaredocLibrary'))
30
- return
31
- endif
32
-
33
- # Fetch and validate the library documentation resource
34
- groups = {}
35
- urls = if(systemType(url) == 'array', url, [url])
36
- for libraryJSON, ixLibrary in systemFetch(urls):
37
- libraryPart = if(libraryJSON != null, jsonParse(libraryJSON))
38
- libraryPart = if(libraryPart != null, schemaValidate(baredocTypes, 'BaredocLibrary', libraryPart))
39
- if libraryPart == null:
40
- libraryURL = arrayGet(urls, ixLibrary)
41
- markdownPrint('**Error:** Failed to fetch library documentation resource "' + markdownEscape(libraryURL) + '"')
42
- return
43
- endif
44
-
45
- # Group the function documentation
46
- for function_ in objectGet(libraryPart, 'functions'):
47
- groupName = objectGet(function_, 'group')
48
- groupFunctions = objectGet(groups, groupName)
49
- if groupFunctions == null:
50
- groupFunctions = []
51
- objectSet(groups, groupName, groupFunctions)
52
- endif
53
- arrayPush(groupFunctions, function_)
54
- endfor
55
- endfor
56
-
57
- # Group URLs?
58
- if groupURLs != null:
59
- # Fetch the group URLs, if necessary
60
- if systemType(groupURLs) == 'string':
61
- groupURLs = jsonParse(systemFetch(groupURLs))
62
- endif
63
-
64
- # Add an empty group for any missing group URLs
65
- for groupName in objectKeys(groupURLs):
66
- if groupName != '' && !objectHas(groups, groupName):
67
- objectSet(groups, groupName, [])
68
- endif
69
- endfor
70
- endif
71
-
72
- # Sort the group functions
73
- for groupName in objectKeys(groups):
74
- groupFunctions = objectGet(groups, groupName)
75
- arraySort(groupFunctions, baredocFunctionCompare)
76
-
77
- # Function requested by name?
78
- if name != null:
79
- for function_ in groupFunctions:
80
- functionName = objectGet(function_, 'name')
81
- if functionName == name:
82
- # Redirect to the actual URL
83
- windowSetLocation( \
84
- argsURL(baredocArguments, {'group': objectGet(function_, 'group'), 'name': null}, false, functionName) \
85
- )
86
- return
87
- endif
88
- endfor
89
- endif
90
- endfor
91
- if name != null:
92
- markdownPrint('', '**Error:** Unknown function "' + markdownEscape(name) + '"')
93
- return
94
- endif
95
-
96
- # Fetch the group content URLs
97
- groupContent = {}
98
- if groupURLs != null:
99
- # Fetch the content URLs
100
- groupURLArray = []
101
- groupNames = arraySort(objectKeys(groupURLs))
102
- for groupName in groupNames:
103
- arrayPush(groupURLArray, objectGet(groupURLs, groupName))
104
- endfor
105
- groupContentArray = systemFetch(groupURLArray)
106
-
107
- # Assign the group contents
108
- for groupName, ixGroupName in groupNames:
109
- objectSet(groupContent, groupName, arrayGet(groupContentArray, ixGroupName))
110
- endfor
111
- endif
112
-
113
- # Render the page
114
- title = if(title != null && !objectHas(args, 'url'), title, url)
115
- if group != null:
116
- baredocGroupPage(args, title, groupURLs, groupContent, groups, group)
117
- elif single:
118
- baredocSinglePage(args, title, menuLinks, groupURLs, groupContent, groups)
119
- else:
120
- baredocIndexPage(args, title, menuLinks, groupURLs, groupContent, groups)
121
- endif
122
- endfunction
123
-
124
-
125
- # The BareScript library documentation application arguments
126
- baredocArguments = argsValidate([ \
127
- {'name': 'doc', 'type': 'bool', 'default': false}, \
128
- {'name': 'group'}, \
129
- {'name': 'name'}, \
130
- {'name': 'publish', 'type': 'bool', 'default': false}, \
131
- {'name': 'single', 'type': 'bool', 'default': false}, \
132
- {'name': 'url', 'global': 'vURL'} \
133
- ])
134
-
135
-
136
- # Helper to compare library function objects by name
137
- function baredocFunctionCompare(f1, f2):
138
- f1Name = objectGet(f1, 'name')
139
- f2Name = objectGet(f2, 'name')
140
- return if(f1Name < f2Name, -1, if(f1Name == f2Name, 0, 1))
141
- endfunction
142
-
143
-
144
- # Render a library documentation index page
145
- function baredocIndexPage(args, title, menuLinks, groupURLs, groupContent, groups):
146
- publish = objectGet(args, 'publish')
147
-
148
- # Render the menu and title
149
- documentSetTitle(title)
150
- if menuLinks != null && arrayLength(menuLinks) > 0 && !publish:
151
- menuSpacer = '&nbsp;|&nbsp;'
152
- for menuLink, ixMenuLink in menuLinks:
153
- menuLinkText = arrayGet(menuLink, 0)
154
- menuLinkURL = arrayGet(menuLink, 1)
155
- markdownPrint(if(ixMenuLink == 0, '', menuSpacer) + '[' + markdownEscape(menuLinkText) + '](' + urlEncode(menuLinkURL) + ')')
156
- endfor
157
- markdownPrint('')
158
- endif
159
- markdownPrint('# ' + markdownEscape(title))
160
-
161
- # Render the index Markdown, if any
162
- if objectHas(groupContent, ''):
163
- rootURL = objectGet(groupURLs, '')
164
- rootMarkdown = objectGet(groupContent, '')
165
- markdownPrint('', if(rootMarkdown != null, rootMarkdown, '**Error:** Failed to load "' + markdownEscape(rootURL) + '"'))
166
- endif
167
-
168
- # Render the single page toggle
169
- if !publish:
170
- markdownPrint('', argsLink(baredocArguments, 'Single Page', {'single': true}))
171
- endif
172
-
173
- # Render the library function index
174
- markdownPrint('', '## Table of Contents', '')
175
- for groupName in arraySort(objectKeys(groups)):
176
- markdownPrint('- ' + argsLink(baredocArguments, groupName, {'group': groupName}, false, argsTopHeaderId))
177
- endfor
178
- endfunction
179
-
180
-
181
- # Render the single-page library documentation
182
- function baredocSinglePage(args, title, menuLinks, groupURLs, groupContent, groups):
183
- publish = objectGet(args, 'publish')
184
-
185
- # Render the menu and title
186
- documentSetTitle(title)
187
- if menuLinks != null && arrayLength(menuLinks) > 0 && !publish:
188
- menuSpacer = '&nbsp;|&nbsp;'
189
- for menuLink, ixMenuLink in menuLinks:
190
- menuLinkText = arrayGet(menuLink, 0)
191
- menuLinkURL = arrayGet(menuLink, 1)
192
- markdownPrint(if(ixMenuLink == 0, '', menuSpacer) + '[' + markdownEscape(menuLinkText) + '](' + urlEncode(menuLinkURL) + ')')
193
- endfor
194
- markdownPrint('')
195
- endif
196
- markdownPrint('# ' + markdownEscape(title))
197
-
198
- # Render the index Markdown, if any
199
- if objectHas(groupContent, ''):
200
- rootURL = objectGet(groupURLs, '')
201
- rootMarkdown = objectGet(groupContent, '')
202
- markdownPrint('', if(rootMarkdown != null, rootMarkdown, '**Error:** Failed to load "' + markdownEscape(rootURL) + '"'))
203
- endif
204
-
205
- # Render the single page toggle
206
- if !publish:
207
- markdownPrint('', argsLink(baredocArguments, 'Multi Page', {'single': false}))
208
- endif
209
-
210
- # The table of contents
211
- markdownPrint('', '## Table of Contents', '')
212
- for groupName in arraySort(objectKeys(groups)):
213
- markdownPrint('- ' + argsLink(baredocArguments, groupName, null, false, groupName))
214
- endfor
215
-
216
- # Render the library function index
217
- for groupName in arraySort(objectKeys(groups)):
218
- markdownPrint('', '---', '')
219
- baredocGroupPage(args, title, groupURLs, groupContent, groups, groupName)
220
- endfor
221
- endfunction
222
-
223
-
224
- # Render a library documentation group page
225
- function baredocGroupPage(args, title, groupURLs, groupContent, groups, groupName):
226
- publish = objectGet(args, 'publish')
227
- single = objectGet(args, 'single')
228
- baseHeader = if(single, '##', '#')
229
-
230
- if !single:
231
- # Set the document title
232
- documentSetTitle(title + ' - ' + groupName)
233
-
234
- # Group exist?
235
- if !objectHas(groups, groupName):
236
- markdownPrint('', '**Error:** Unknown group "' + markdownEscape(groupName) + '"')
237
- return
238
- endif
239
- endif
240
-
241
- # Render the menu and title
242
- if !single:
243
- markdownPrint(argsLink(baredocArguments, 'Index', {'group': null}), '')
244
- endif
245
- markdownPrint(baseHeader + ' ' + markdownEscape(groupName))
246
- if single && !publish:
247
- markdownPrint('', argsLink(baredocArguments, 'Back to top', null, false, '_top'))
248
- endif
249
-
250
- # Render the group Markdown, if any
251
- if objectHas(groupContent, groupName):
252
- groupURL = objectGet(groupURLs, groupName)
253
- groupMarkdown = objectGet(groupContent, groupName)
254
- markdownPrint('', if(groupMarkdown != null, groupMarkdown, '**Error:** Failed to load "' + markdownEscape(groupURL) + '"'))
255
- endif
256
-
257
- # Render the group function index
258
- groupFunctions = objectGet(groups, groupName)
259
- if arrayLength(groupFunctions) != 0:
260
- markdownPrint('', baseHeader + '# Function Index', '')
261
- endif
262
- for function_, ixFunction in groupFunctions:
263
- functionName = objectGet(function_, 'name')
264
- markdownPrint('- ' + argsLink(baredocArguments, functionName, null, false, functionName))
265
- endfor
266
-
267
- # Render the group function documentation
268
- for function_ in groupFunctions:
269
- # Render the function header
270
- markdownPrint( \
271
- '', \
272
- '---', \
273
- '', \
274
- baseHeader + '# ' + markdownEscape(objectGet(function_, 'name')), \
275
- '', \
276
- objectGet(function_, 'doc') \
277
- )
278
-
279
- # Render the functions's argument documentation
280
- markdownPrint('', baseHeader + '## Arguments')
281
- arguments = objectGet(function_, 'args')
282
- if arguments != null:
283
- for argument in arguments:
284
- markdownPrint('', '**' + markdownEscape(objectGet(argument, 'name')) + ' -**', objectGet(argument, 'doc'))
285
- endfor
286
- else:
287
- markdownPrint('', 'None')
288
- endif
289
-
290
- # Render the function's return documentation
291
- markdownPrint('', baseHeader + '## Returns')
292
- returnDoc = objectGet(function_, 'return')
293
- markdownPrint('', if(returnDoc != null, returnDoc, 'Nothing'))
294
- endfor
295
- endfunction
296
-
297
-
298
- # The library documentation schema
299
- baredocTypes = schemaParse( \
300
- 'group "baredoc.bare"', \
301
- '', \
302
- '', \
303
- '# A library documentation model', \
304
- 'struct BaredocLibrary', \
305
- '', \
306
- ' # The library functions', \
307
- ' BaredocFunction[] functions', \
308
- '', \
309
- '', \
310
- '# A library function', \
311
- 'struct BaredocFunction', \
312
- '', \
313
- ' # The function name', \
314
- ' string name', \
315
- '', \
316
- ' # The function group (e.g. "Math")', \
317
- ' string group', \
318
- '', \
319
- " # The function's documentation Markdown lines", \
320
- ' string[] doc', \
321
- '', \
322
- ' # The function arguments', \
323
- ' optional BaredocFunctionArgument[] args', \
324
- '', \
325
- " # The function return's documentation Markdown lines", \
326
- ' optional string[] return', \
327
- '', \
328
- ' # If true, ignore the function', \
329
- ' optional bool ignore', \
330
- '', \
331
- '', \
332
- '# A function argument', \
333
- 'struct BaredocFunctionArgument', \
334
- '', \
335
- ' # The argument name', \
336
- ' string name', \
337
- '', \
338
- " # The argument's documentation Markdown lines", \
339
- ' string[] doc' \
340
- )
File without changes
File without changes
File without changes