blob: 6c3ecab0c11898e8fa34fe7fcdd4fd011f140388 [file] [log] [blame]
Gavin Howard5715b042018-02-12 16:11:42 -07001/*
Gavin Howardb5904bf2018-02-20 13:28:18 -07002 * *****************************************************************************
Gavin Howard5715b042018-02-12 16:11:42 -07003 *
Gavin Howardb5904bf2018-02-20 13:28:18 -07004 * Copyright 2018 Gavin D. Howard
Gavin Howard5715b042018-02-12 16:11:42 -07005 *
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11 * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
14 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15 * PERFORMANCE OF THIS SOFTWARE.
16 *
Gavin Howardb5904bf2018-02-20 13:28:18 -070017 * *****************************************************************************
Gavin Howard5715b042018-02-12 16:11:42 -070018 *
19 * Definitions for bc's parser.
20 *
21 */
22
Gavin Howard8a596d42018-01-15 15:46:01 -070023#ifndef BC_PARSE_H
24#define BC_PARSE_H
25
26#include <stdbool.h>
27#include <stdint.h>
28
Gavin Howard3ba6c8d2018-02-15 12:23:35 -070029#include <vector.h>
30#include <program.h>
31#include <lex.h>
Gavin Howard8a596d42018-01-15 15:46:01 -070032
Gavin Howardac54c142018-01-16 01:48:45 -070033#define BC_PARSE_TOP_FLAG_PTR(parse) \
Gavin Howardd96bcae2018-02-07 19:16:19 -070034 ((uint8_t*) bc_vec_top(&(parse)->flags))
Gavin Howardac54c142018-01-16 01:48:45 -070035
Gavin Howarde46c6822018-02-08 20:05:39 -070036#define BC_PARSE_TOP_FLAG(parse) \
37 (*(BC_PARSE_TOP_FLAG_PTR(parse)))
Gavin Howardd133fb52018-01-16 14:44:40 -070038
Gavin Howard03d27952018-01-15 18:48:17 -070039#define BC_PARSE_FLAG_FUNC_INNER (0x01)
Gavin Howard8a596d42018-01-15 15:46:01 -070040
41#define BC_PARSE_FUNC_INNER(parse) \
Gavin Howard4bc73ee2018-01-26 11:39:20 -070042 (BC_PARSE_TOP_FLAG(parse) & BC_PARSE_FLAG_FUNC_INNER)
Gavin Howard8a596d42018-01-15 15:46:01 -070043
Gavin Howard03d27952018-01-15 18:48:17 -070044#define BC_PARSE_FLAG_FUNC (0x02)
Gavin Howard8a596d42018-01-15 15:46:01 -070045
46#define BC_PARSE_FUNC(parse) \
Gavin Howard4bc73ee2018-01-26 11:39:20 -070047 (BC_PARSE_TOP_FLAG(parse) & BC_PARSE_FLAG_FUNC)
Gavin Howard8a596d42018-01-15 15:46:01 -070048
Gavin Howard1e6793b2018-03-06 13:40:48 -070049#define BC_PARSE_FLAG_BODY (0x04)
Gavin Howard8a596d42018-01-15 15:46:01 -070050
Gavin Howard1e6793b2018-03-06 13:40:48 -070051#define BC_PARSE_BODY(parse) \
52 (BC_PARSE_TOP_FLAG(parse) & BC_PARSE_FLAG_BODY)
Gavin Howard8a596d42018-01-15 15:46:01 -070053
Gavin Howarde46c6822018-02-08 20:05:39 -070054#define BC_PARSE_FLAG_LOOP (0x08)
Gavin Howard8a596d42018-01-15 15:46:01 -070055
Gavin Howarde46c6822018-02-08 20:05:39 -070056#define BC_PARSE_LOOP(parse) \
57 (BC_PARSE_TOP_FLAG(parse) & BC_PARSE_FLAG_LOOP)
Gavin Howard8a596d42018-01-15 15:46:01 -070058
Gavin Howarde46c6822018-02-08 20:05:39 -070059#define BC_PARSE_FLAG_LOOP_INNER (0x10)
Gavin Howard8a596d42018-01-15 15:46:01 -070060
61#define BC_PARSE_LOOP_INNER(parse) \
Gavin Howard4bc73ee2018-01-26 11:39:20 -070062 (BC_PARSE_TOP_FLAG(parse) & BC_PARSE_FLAG_LOOP_INNER)
Gavin Howard8a596d42018-01-15 15:46:01 -070063
Gavin Howarde46c6822018-02-08 20:05:39 -070064#define BC_PARSE_FLAG_IF (0x20)
Gavin Howard8a596d42018-01-15 15:46:01 -070065
66#define BC_PARSE_IF(parse) \
Gavin Howard4bc73ee2018-01-26 11:39:20 -070067 (BC_PARSE_TOP_FLAG(parse) & BC_PARSE_FLAG_IF)
Gavin Howard8a596d42018-01-15 15:46:01 -070068
Gavin Howarde46c6822018-02-08 20:05:39 -070069#define BC_PARSE_FLAG_ELSE (0x40)
Gavin Howard8a596d42018-01-15 15:46:01 -070070
71#define BC_PARSE_ELSE(parse) \
Gavin Howard4bc73ee2018-01-26 11:39:20 -070072 (BC_PARSE_TOP_FLAG(parse) & BC_PARSE_FLAG_ELSE)
Gavin Howard8a596d42018-01-15 15:46:01 -070073
Gavin Howarde46c6822018-02-08 20:05:39 -070074#define BC_PARSE_FLAG_IF_END (0x80)
75
76#define BC_PARSE_IF_END(parse) \
77 (BC_PARSE_TOP_FLAG(parse) & BC_PARSE_FLAG_IF_END)
78
Gavin Howard8a596d42018-01-15 15:46:01 -070079#define BC_PARSE_CAN_EXEC(parse) \
Gavin Howard4bc73ee2018-01-26 11:39:20 -070080 (!(BC_PARSE_TOP_FLAG(parse) & (BC_PARSE_FLAG_FUNC_INNER | \
81 BC_PARSE_FLAG_FUNC | \
Gavin Howard1e6793b2018-03-06 13:40:48 -070082 BC_PARSE_FLAG_BODY | \
Gavin Howarde46c6822018-02-08 20:05:39 -070083 BC_PARSE_FLAG_LOOP | \
Gavin Howard4bc73ee2018-01-26 11:39:20 -070084 BC_PARSE_FLAG_LOOP_INNER | \
Gavin Howarde46c6822018-02-08 20:05:39 -070085 BC_PARSE_FLAG_IF | \
86 BC_PARSE_FLAG_ELSE | \
Gavin Howard1e6793b2018-03-06 13:40:48 -070087 BC_PARSE_FLAG_IF_END)))
Gavin Howard8a596d42018-01-15 15:46:01 -070088
89// We can calculate the conversion between tokens and exprs
90// by subtracting the position of the first operator in the
91// lex enum and adding the position of the first in the expr
Gavin Howardbde073f2018-02-26 17:48:36 -070092// enum. Note: This only works for binary operators.
Gavin Howard8a596d42018-01-15 15:46:01 -070093#define BC_PARSE_TOKEN_TO_EXPR(type) ((type) - BC_LEX_OP_POWER + BC_EXPR_POWER)
94
95typedef struct BcOp {
96
Gavin Howard4bc73ee2018-01-26 11:39:20 -070097 uint8_t prec;
98 bool left;
Gavin Howard8a596d42018-01-15 15:46:01 -070099
100} BcOp;
101
102typedef struct BcParse {
103
Gavin Howard4bc73ee2018-01-26 11:39:20 -0700104 BcLex lex;
105 BcLexToken token;
Gavin Howard8a596d42018-01-15 15:46:01 -0700106
Gavin Howardd96bcae2018-02-07 19:16:19 -0700107 BcVec flags;
Gavin Howard8a596d42018-01-15 15:46:01 -0700108
Gavin Howarde46c6822018-02-08 20:05:39 -0700109 BcVec exit_labels;
Gavin Howardd96bcae2018-02-07 19:16:19 -0700110
Gavin Howarde46c6822018-02-08 20:05:39 -0700111 BcVec cond_labels;
Gavin Howard8a596d42018-01-15 15:46:01 -0700112
Gavin Howard26a5aeb2018-02-05 14:33:40 -0700113 BcVec ops;
Gavin Howardde382112018-01-16 20:53:57 -0700114
Gavin Howard8d1f1db2018-02-23 11:29:41 -0700115 BcProgram *program;
Gavin Howardd96bcae2018-02-07 19:16:19 -0700116 size_t func;
Gavin Howard8a596d42018-01-15 15:46:01 -0700117
Gavin Howard4bc73ee2018-01-26 11:39:20 -0700118 uint32_t num_braces;
Gavin Howard8a596d42018-01-15 15:46:01 -0700119
Gavin Howard4bc73ee2018-01-26 11:39:20 -0700120 bool auto_part;
Gavin Howardac54c142018-01-16 01:48:45 -0700121
Gavin Howard8a596d42018-01-15 15:46:01 -0700122} BcParse;
123
Gavin Howardb4d60492018-02-28 13:33:36 -0700124#define BC_PARSE_EXPR_POSIX_REL (1<<0)
125#define BC_PARSE_EXPR_PRINT (1<<1)
126#define BC_PARSE_EXPR_NO_CALL (1<<2)
127#define BC_PARSE_EXPR_NO_READ (1<<3)
128
Gavin Howardd75aaec2018-03-10 20:33:39 -0700129// ** Exclude start. **
Gavin Howard8d1f1db2018-02-23 11:29:41 -0700130BcStatus bc_parse_init(BcParse *parse, BcProgram *program);
131BcStatus bc_parse_file(BcParse *parse, const char *file);
132BcStatus bc_parse_text(BcParse *parse, const char *text);
Gavin Howard8a596d42018-01-15 15:46:01 -0700133
Gavin Howard8d1f1db2018-02-23 11:29:41 -0700134BcStatus bc_parse_parse(BcParse *parse);
Gavin Howard8a596d42018-01-15 15:46:01 -0700135
Gavin Howard8d1f1db2018-02-23 11:29:41 -0700136void bc_parse_free(BcParse *parse);
Gavin Howardd75aaec2018-03-10 20:33:39 -0700137// ** Exclude end. **
138
139BcStatus bc_parse_expr(BcParse *parse, BcVec *code, uint8_t flags);
Gavin Howard8a596d42018-01-15 15:46:01 -0700140
Gavin Howardf456d372018-03-10 20:11:41 -0700141extern const bool bc_parse_token_exprs[];
142extern const BcOp bc_parse_ops[];
143extern const uint8_t bc_parse_insts[];
144
Gavin Howard8a596d42018-01-15 15:46:01 -0700145#endif // BC_PARSE_H