Numworks Epsilon  1.4.1
Graphing Calculator Operating System
script_store.cpp
Go to the documentation of this file.
1 #include "script_store.h"
2 #include "string.h"
3 #include <stddef.h>
4 
5 extern "C" {
6 #include "py/lexer.h"
7 #include "py/nlr.h"
8 }
9 
10 namespace Code {
11 
12 constexpr char ScriptStore::k_scriptExtension[];
13 constexpr char ScriptStore::k_defaultScriptName[];
14 
16 {
20 }
21 
23  for (int i = numberOfScripts() - 1; i >= 0; i--) {
25  }
26 }
27 
29  return (numberOfScripts() >= k_maxNumberOfScripts || Ion::Storage::sharedStorage()->availableSize() < k_fullFreeSpaceSizeLimit);
30 }
31 
32 void ScriptStore::scanScriptsForFunctionsAndVariables(void * context, ScanCallback storeFunction, ScanCallback storeVariable) {
33  for (int scriptIndex = 0; scriptIndex < numberOfScripts(); scriptIndex++) {
34  // Handle lexer or parser errors with nlr.
35  nlr_buf_t nlr;
36  if (nlr_push(&nlr) == 0) {
37  const char * scriptContent = scriptAtIndex(scriptIndex).readContent();
38  if (scriptContent == nullptr) {
39  continue;
40  }
41  mp_lexer_t *lex = mp_lexer_new_from_str_len(0, scriptContent, strlen(scriptContent), false);
43  mp_parse_node_t pn = parseTree.root;
44 
45  if (!MP_PARSE_NODE_IS_STRUCT(pn)) {
46  mp_parse_tree_clear(&parseTree);
47  nlr_pop();
48  continue;
49  }
50 
52 
53  // The script is only a single function definition.
54  if (((uint)(MP_PARSE_NODE_STRUCT_KIND(pns))) == k_functionDefinitionParseNodeStructKind) {
55  const char * id = structID(pns);
56  if (id == nullptr) {
57  continue;
58  }
59  storeFunction(context, id, scriptIndex);
60  mp_parse_tree_clear(&parseTree);
61  nlr_pop();
62  continue;
63  }
64 
65  // The script is only a single global variable definition.
66  if (((uint)(MP_PARSE_NODE_STRUCT_KIND(pns))) == k_expressionStatementParseNodeStructKind) {
67  const char * id = structID(pns);
68  if (id == nullptr) {
69  continue;
70  }
71  storeVariable(context, id, scriptIndex);
72  mp_parse_tree_clear(&parseTree);
73  nlr_pop();
74  continue;
75  }
76 
77  if (((uint)(MP_PARSE_NODE_STRUCT_KIND(pns))) != k_fileInput2ParseNodeStructKind) {
78  // The script node is not of type "file_input_2", thus it will not have main
79  // structures of the wanted type.
80  mp_parse_tree_clear(&parseTree);
81  nlr_pop();
82  continue;
83  }
84 
85  // Count the number of structs in child nodes.
86 
87  size_t n = MP_PARSE_NODE_STRUCT_NUM_NODES(pns);
88  for (size_t i = 0; i < n; i++) {
89  mp_parse_node_t child = pns->nodes[i];
90  if (MP_PARSE_NODE_IS_STRUCT(child)) {
91  mp_parse_node_struct_t *child_pns = (mp_parse_node_struct_t*)(child);
92  if (((uint)(MP_PARSE_NODE_STRUCT_KIND(child_pns))) == k_functionDefinitionParseNodeStructKind) {
93  const char * id = structID(child_pns);
94  if (id == nullptr) {
95  continue;
96  }
97  storeFunction(context, id, scriptIndex);
98  } else if (((uint)(MP_PARSE_NODE_STRUCT_KIND(child_pns))) == k_expressionStatementParseNodeStructKind) {
99  const char * id = structID(child_pns);
100  if (id == nullptr) {
101  continue;
102  }
103  storeVariable(context, id, scriptIndex);
104  }
105  }
106  }
107 
108  mp_parse_tree_clear(&parseTree);
109  nlr_pop();
110  }
111  }
112 }
113 
114 const char * ScriptStore::contentOfScript(const char * name) {
115  Script script = scriptNamed(name);
116  if (script.isNull()) {
117  return nullptr;
118  }
119  return script.readContent();
120 }
121 
123  size_t scriptSize = strlen(scriptTemplate->content())+1;
124  char * body = new char[scriptSize+Script::k_importationStatusSize];
125  body[0] = 1;
126  strlcpy(body+Script::k_importationStatusSize, scriptTemplate->content(), scriptSize);
129  delete[] body;
130  return err;
131 }
132 
133 const char * ScriptStore::structID(mp_parse_node_struct_t *structNode) {
134  // Find the id child node, which stores the struct's name
135  size_t childNodesCount = MP_PARSE_NODE_STRUCT_NUM_NODES(structNode);
136  if (childNodesCount < 1) {
137  return nullptr;
138  }
139  mp_parse_node_t child = structNode->nodes[0];
140  if (MP_PARSE_NODE_IS_LEAF(child)
142  {
143  uintptr_t arg = MP_PARSE_NODE_LEAF_ARG(child);
144  return qstr_str(arg);
145  }
146  return nullptr;
147 }
148 
149 }
mp_parse_node_t root
Definition: parse.h:98
const char * qstr_str(qstr q)
Definition: qstr.c:278
Ion::Storage::Record::ErrorStatus addScriptFromTemplate(const ScriptTemplate *scriptTemplate)
#define assert(e)
Definition: assert.h:9
mp_parse_node_t nodes[]
Definition: parse.h:57
bool isNull() const
Definition: storage.h:38
#define MP_PARSE_NODE_STRUCT_KIND(pns)
Definition: parse.h:76
#define nlr_push(buf)
Definition: nlr.h:73
#define MP_PARSE_NODE_LEAF_KIND(pn)
Definition: parse.h:73
static constexpr int k_maxNumberOfScripts
Definition: script_store.h:18
Record::ErrorStatus createRecord(const char *name, const void *data, size_t size)
Definition: storage.cpp:60
mp_lexer_t * mp_lexer_new_from_str_len(qstr src_name, const char *str, size_t len, size_t free_len)
unsigned int uintptr_t
Definition: stdint.h:14
size_t strlcpy(char *dst, const char *src, size_t len)
Definition: strlcpy.c:3
uintptr_t mp_parse_node_t
Definition: parse.h:52
const char * readContent() const
Definition: script.cpp:22
#define MP_PARSE_NODE_STRUCT_NUM_NODES(pns)
Definition: parse.h:77
static Storage * sharedStorage()
Definition: storage.cpp:22
Script scriptNamed(const char *name)
Definition: script_store.h:24
Definition: app.cpp:7
const char * contentOfScript(const char *name) override
size_t strlen(const char *s)
Definition: strlen.c:3
Script scriptAtIndex(int index)
Definition: script_store.h:21
#define MP_PARSE_NODE_ID
Definition: parse.h:47
static const ScriptTemplate * Mandelbrot()
void scanScriptsForFunctionsAndVariables(void *context, ScanCallback storeFunction, ScanCallback storeVariable)
#define nlr_pop()
Definition: nlr.h:74
mp_parse_tree_t mp_parse(struct _mp_lexer_t *lex, mp_parse_input_kind_t input_kind)
#define MP_PARSE_NODE_LEAF_ARG(pn)
Definition: parse.h:74
const char * content() const
Definition: nlr.h:39
#define MP_PARSE_NODE_IS_STRUCT(pn)
Definition: parse.h:65
const char * name() const
static const ScriptTemplate * Factorial()
#define MP_PARSE_NODE_IS_LEAF(pn)
Definition: parse.h:64
void mp_parse_tree_clear(mp_parse_tree_t *tree)
static constexpr char k_defaultScriptName[]
Definition: script_store.h:17
static const ScriptTemplate * Polynomial()
static constexpr char k_scriptExtension[]
Definition: script_store.h:16
static constexpr size_t k_importationStatusSize
Definition: script.h:21
unsigned int uint
Definition: misc.h:38