aboutsummaryrefslogtreecommitdiffstats
path: root/parser.h
blob: f3c65d0b74fee6afb73d21d154f2ed26dd50f25e (plain)
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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/**
 * @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);

/**
 * Parses the given line of script, and adds it to the end of the instance's
 * stored script.
 * @param it the instance to use
 * @param s the line to load
 * @return zero for success, otherwise error
 */
int iaddline(instance *it, const char *s);

/**
 * Runs the instance with its loaded script until there's nothing more to run.
 * @param the instance to use
 * @return an error code, or zero if success
 */
int irun(instance *it);

/**
 * 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);

/**
 * Creates a script-accessible float number.
 * @param it the current instance
 * @param name the name of the new variable
 * @param f the variable's initial value
 */
void inew_number(instance *it, const char *name, float f);

/**
 * 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_