1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
/**
* @file parser.h
* Main library component; parses, manages and runs script
*
* Copyright (C) 2018 Clyne Sullivan
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef PARSER_H_
#define PARSER_H_
#include "variable.h"
#include <stdint.h>
/**
* Contains data for an 'instance' of script.
* Multiple instances can be created to run different scripts at once.
*/
typedef struct {
variable *vars; /**< An array of defined variables */
char **names; /**< An array of names for the variables */
uint32_t *stack; /**< The instance's stack */
uint32_t stidx; /**< The instance's position in the stack */
variable ***lines; /**< Compiled data for each line of script */
uint32_t lnidx; /**< Position in script/line being run */
variable *ret; /**< Pointer to the last returned variable */
uint8_t indent; /**< Current indent/scope of the instance */
uint8_t sindent; /**< Indent of scope to skip, for false conditionals */
} instance;
/**
* A flag to set in instance.sindent to determine if code should be skipped
* over.
*/
#define SKIP (1 << 7)
typedef int (*func_t)(instance *);
/**
* Creates a new parser instance, loading the built-in library into it.
* @return a new, malloc'd instance
*/
instance *inewinstance(void);
/**
* Destroys an instance, freeing all used memory including for the instance
* itself.
* @param it the instance to destroy
*/
void idelinstance(instance *it);
/**
* Adds and runs the line through the parser instance.
* This parses and runs the line, while storing it at the current line index.
* @param it the current instance
* @param s the line to parse/run
*/
int idoline(instance *it, const char *s);
/**
* Makes a C function visible to the script.
* @param it the current instance
* @param name the name of the function when called from the script
* @param func the C function
*/
void inew_cfunc(instance *it, const char *name, func_t func);
/**
* Pops a word from the instance's stack.
* @param it the current instance
* @return the popped value
*/
uint32_t ipop(instance *it);
/**
* Pushes a word to the instance's stack.
* @param it the current instance
* @param v the word to push
*/
void ipush(instance *it, uint32_t v);
/**
* Gets the nth argument passed to the current C function.
* This call has no protections.
* @param it the current instance
* @param n the index of the argument, zero-based
* @return the argument's variable
*/
variable *igetarg(instance *it, uint32_t n);
/**
* Parses the given line, returning compiled data to run.
* For internal use only.
* @param it the current instance
* @param s the string to parse
* @return the 'compiled code'
*/
variable **iparse(instance *it, const char *s);
/**
* 'Solves' (runs) the given compiled data, returning what the line returns.
* For internal use only.
* @param it the current instance
* @param ops the compiled data to run
* @param count the size of the ops array, zero if unknown
* @return the variable returned by the line, null if none
*/
variable *isolve(instance *it, variable **ops, uint32_t count);
#endif // PARSER_H_
|