blob: d275aa6090e4fa761bbfa3430a125de04cb65a91 [file] [log] [blame]
Brian Callahan1c761962019-04-02 18:37:44 -04001/*
Gavin Howardb5904bf2018-02-20 13:28:18 -07002 * *****************************************************************************
Gavin Howard5715b042018-02-12 16:11:42 -07003 *
Gavin Howard7345cb92019-04-08 14:13:43 -06004 * Copyright (c) 2018-2019 Gavin D. Howard and contributors.
Gavin Howard5715b042018-02-12 16:11:42 -07005 *
Gavin Howard7345cb92019-04-08 14:13:43 -06006 * All rights reserved.
Gavin Howard5715b042018-02-12 16:11:42 -07007 *
Gavin Howard7345cb92019-04-08 14:13:43 -06008 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are met:
10 *
11 * * Redistributions of source code must retain the above copyright notice, this
12 * list of conditions and the following disclaimer.
13 *
14 * * Redistributions in binary form must reproduce the above copyright notice,
15 * this list of conditions and the following disclaimer in the documentation
16 * and/or other materials provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
Gavin Howard5715b042018-02-12 16:11:42 -070029 *
Gavin Howardb5904bf2018-02-20 13:28:18 -070030 * *****************************************************************************
Gavin Howard5715b042018-02-12 16:11:42 -070031 *
Gavin Howard4ffe5a92018-09-26 20:58:31 -060032 * Definitions for bc.
Gavin Howard5715b042018-02-12 16:11:42 -070033 *
34 */
35
Gavin Howard4ffe5a92018-09-26 20:58:31 -060036#ifndef BC_BC_H
37#define BC_BC_H
Gavin Howard8a596d42018-01-15 15:46:01 -070038
Gavin Howard1545ffe2018-12-24 11:26:46 -070039#if BC_ENABLED
40
Gavin Howardc1902aa2018-12-20 15:54:28 -070041#include <limits.h>
Gavin Howard707a4e32018-10-03 16:36:41 -060042#include <stdbool.h>
43
Gavin Howard29493062018-03-20 19:57:37 -060044#include <status.h>
Gavin Howard707a4e32018-10-03 16:36:41 -060045#include <lex.h>
46#include <parse.h>
Gavin Howard6839e4d2018-03-20 21:24:52 -060047
Gavin Howarda84ad992018-12-03 19:11:06 -070048int bc_main(int argc, char **argv);
49
Gavin Howardd5551672018-09-22 19:52:42 -060050extern const char bc_help[];
Gavin Howard1cbfe242019-01-09 17:13:11 -070051extern const char bc_lib[];
52extern const char* bc_lib_name;
53extern const char bc_lib2[];
54extern const char* bc_lib2_name;
Gavin Howard707a4e32018-10-03 16:36:41 -060055
56typedef struct BcLexKeyword {
Gavin Howardc1902aa2018-12-20 15:54:28 -070057 uchar data;
Gavin Howard707a4e32018-10-03 16:36:41 -060058 const char name[9];
Gavin Howard707a4e32018-10-03 16:36:41 -060059} BcLexKeyword;
60
Gavin Howard4662d6c2018-12-20 16:31:31 -070061#define BC_LEX_CHAR_MSB(bit) ((bit) << (CHAR_BIT - 1))
62
Gavin Howardfbd2b4a2018-12-27 12:11:41 -070063#define BC_LEX_KW_POSIX(kw) ((kw)->data & (BC_LEX_CHAR_MSB(1)))
64#define BC_LEX_KW_LEN(kw) ((size_t) ((kw)->data & ~(BC_LEX_CHAR_MSB(1))))
Gavin Howard4662d6c2018-12-20 16:31:31 -070065
Gavin Howardc1902aa2018-12-20 15:54:28 -070066#define BC_LEX_KW_ENTRY(a, b, c) \
Gavin Howarded38e942018-12-21 15:09:13 -070067 { .data = ((b) & ~(BC_LEX_CHAR_MSB(1))) | BC_LEX_CHAR_MSB(c),.name = a }
Gavin Howard707a4e32018-10-03 16:36:41 -060068
Gavin Howardc70bd502018-12-31 17:28:32 -070069extern const BcLexKeyword bc_lex_kws[];
70extern const size_t bc_lex_kws_len;
Gavin Howard707a4e32018-10-03 16:36:41 -060071
72BcStatus bc_lex_token(BcLex *l);
73
Gavin Howardb15fa032019-01-02 14:42:36 -070074#define BC_PARSE_TOP_FLAG_PTR(p) ((uint16_t*) bc_vec_top(&(p)->flags))
75#define BC_PARSE_TOP_FLAG(p) (*(BC_PARSE_TOP_FLAG_PTR(p)))
76
Gavin Howardf2d9a652019-05-11 07:38:32 -060077#define BC_PARSE_FLAG_BRACE (UINTMAX_C(1)<<0)
Gavin Howardb15fa032019-01-02 14:42:36 -070078#define BC_PARSE_BRACE(p) (BC_PARSE_TOP_FLAG(p) & BC_PARSE_FLAG_BRACE)
79
Gavin Howardf2d9a652019-05-11 07:38:32 -060080#define BC_PARSE_FLAG_FUNC_INNER (UINTMAX_C(1)<<1)
Gavin Howardb15fa032019-01-02 14:42:36 -070081#define BC_PARSE_FUNC_INNER(p) (BC_PARSE_TOP_FLAG(p) & BC_PARSE_FLAG_FUNC_INNER)
82
Gavin Howardf2d9a652019-05-11 07:38:32 -060083#define BC_PARSE_FLAG_FUNC (UINTMAX_C(1)<<2)
Gavin Howardb15fa032019-01-02 14:42:36 -070084#define BC_PARSE_FUNC(p) (BC_PARSE_TOP_FLAG(p) & BC_PARSE_FLAG_FUNC)
85
Gavin Howardf2d9a652019-05-11 07:38:32 -060086#define BC_PARSE_FLAG_BODY (UINTMAX_C(1)<<3)
Gavin Howardb15fa032019-01-02 14:42:36 -070087#define BC_PARSE_BODY(p) (BC_PARSE_TOP_FLAG(p) & BC_PARSE_FLAG_BODY)
88
Gavin Howardf2d9a652019-05-11 07:38:32 -060089#define BC_PARSE_FLAG_LOOP (UINTMAX_C(1)<<4)
Gavin Howardb15fa032019-01-02 14:42:36 -070090#define BC_PARSE_LOOP(p) (BC_PARSE_TOP_FLAG(p) & BC_PARSE_FLAG_LOOP)
91
Gavin Howardf2d9a652019-05-11 07:38:32 -060092#define BC_PARSE_FLAG_LOOP_INNER (UINTMAX_C(1)<<5)
Gavin Howardb15fa032019-01-02 14:42:36 -070093#define BC_PARSE_LOOP_INNER(p) (BC_PARSE_TOP_FLAG(p) & BC_PARSE_FLAG_LOOP_INNER)
94
Gavin Howardf2d9a652019-05-11 07:38:32 -060095#define BC_PARSE_FLAG_IF (UINTMAX_C(1)<<6)
Gavin Howardb15fa032019-01-02 14:42:36 -070096#define BC_PARSE_IF(p) (BC_PARSE_TOP_FLAG(p) & BC_PARSE_FLAG_IF)
97
Gavin Howardf2d9a652019-05-11 07:38:32 -060098#define BC_PARSE_FLAG_ELSE (UINTMAX_C(1)<<7)
Gavin Howardb15fa032019-01-02 14:42:36 -070099#define BC_PARSE_ELSE(p) (BC_PARSE_TOP_FLAG(p) & BC_PARSE_FLAG_ELSE)
100
Gavin Howardf2d9a652019-05-11 07:38:32 -0600101#define BC_PARSE_FLAG_IF_END (UINTMAX_C(1)<<8)
Gavin Howardb15fa032019-01-02 14:42:36 -0700102#define BC_PARSE_IF_END(p) (BC_PARSE_TOP_FLAG(p) & BC_PARSE_FLAG_IF_END)
103
104#define BC_PARSE_NO_EXEC(p) ((p)->flags.len != 1 || BC_PARSE_TOP_FLAG(p) != 0)
105
Gavin Howard7ed50c72019-01-14 11:20:12 -0700106#define BC_PARSE_DELIMITER(t) \
107 ((t) == BC_LEX_SCOLON || (t) == BC_LEX_NLINE || (t) == BC_LEX_EOF)
Gavin Howardb15fa032019-01-02 14:42:36 -0700108
Gavin Howard63fdbfa2019-01-16 09:47:04 -0700109#define BC_PARSE_BLOCK_STMT(f) \
110 ((f) & (BC_PARSE_FLAG_ELSE | BC_PARSE_FLAG_LOOP_INNER))
111
Gavin Howard2b4fde92018-12-24 16:02:24 -0700112#define BC_PARSE_OP(p, l) (((p) & ~(BC_LEX_CHAR_MSB(1))) | (BC_LEX_CHAR_MSB(l)))
Gavin Howard4662d6c2018-12-20 16:31:31 -0700113
Gavin Howard1c6cfb82019-01-21 11:42:34 -0700114#define BC_PARSE_OP_DATA(t) bc_parse_ops[((t) - BC_LEX_OP_INC)]
115#define BC_PARSE_OP_LEFT(op) (BC_PARSE_OP_DATA(op) & BC_LEX_CHAR_MSB(1))
116#define BC_PARSE_OP_PREC(op) (BC_PARSE_OP_DATA(op) & ~(BC_LEX_CHAR_MSB(1)))
Gavin Howard4662d6c2018-12-20 16:31:31 -0700117
Gavin Howard675b5cc2018-12-20 16:55:36 -0700118#define BC_PARSE_EXPR_ENTRY(e1, e2, e3, e4, e5, e6, e7, e8) \
Gavin Howardf2d9a652019-05-11 07:38:32 -0600119 ((UINTMAX_C(e1) << 7) | (UINTMAX_C(e2) << 6) | (UINTMAX_C(e3) << 5) | \
120 (UINTMAX_C(e4) << 4) | (UINTMAX_C(e5) << 3) | (UINTMAX_C(e6) << 2) | \
121 (UINTMAX_C(e7) << 1) | (UINTMAX_C(e8) << 0))
Gavin Howard675b5cc2018-12-20 16:55:36 -0700122
123#define BC_PARSE_EXPR(i) \
Gavin Howard1cbfe242019-01-09 17:13:11 -0700124 (bc_parse_exprs[(((i) & (uchar) ~(0x07)) >> 3)] & (1 << (7 - ((i) & 0x07))))
Gavin Howard675b5cc2018-12-20 16:55:36 -0700125
Gavin Howard890d0c02018-10-30 16:34:50 -0600126#define BC_PARSE_TOP_OP(p) (*((BcLexType*) bc_vec_top(&(p)->ops)))
Gavin Howardb6e5a172018-12-28 17:41:15 -0700127#define BC_PARSE_LEAF(prev, bin_last, rparen) \
128 (!(bin_last) && ((rparen) || bc_parse_inst_isLeaf(prev)))
Gavin Howardf81f9042018-12-27 14:19:53 -0700129#define BC_PARSE_INST_VAR(t) \
Gavin Howardd975dc72019-01-24 15:13:17 -0700130 ((t) >= BC_INST_VAR && (t) <= BC_INST_SCALE && (t) != BC_INST_ARRAY)
Gavin Howard707a4e32018-10-03 16:36:41 -0600131
Gavin Howarde5228882019-01-10 16:08:04 -0700132#define BC_PARSE_PREV_PREFIX(p) \
133 ((p) >= BC_INST_INC_PRE && (p) <= BC_INST_BOOL_NOT)
134#define BC_PARSE_OP_PREFIX(t) ((t) == BC_LEX_OP_BOOL_NOT || (t) == BC_LEX_NEG)
Gavin Howardac7a3c92019-01-10 13:26:29 -0700135
Gavin Howard707a4e32018-10-03 16:36:41 -0600136// We can calculate the conversion between tokens and exprs by subtracting the
Gavin Howard954f9b62018-12-19 15:22:20 -0700137// position of the first operator in the lex enum and adding the position of
138// the first in the expr enum. Note: This only works for binary operators.
139#define BC_PARSE_TOKEN_INST(t) ((uchar) ((t) - BC_LEX_NEG + BC_INST_NEG))
Gavin Howard707a4e32018-10-03 16:36:41 -0600140
Gavin Howard7536dcf2018-12-15 19:27:09 -0700141BcStatus bc_parse_expr(BcParse *p, uint8_t flags);
Gavin Howard707a4e32018-10-03 16:36:41 -0600142
Gavin Howard9d2497d2018-10-29 16:10:21 -0600143BcStatus bc_parse_parse(BcParse *p);
Gavin Howard7536dcf2018-12-15 19:27:09 -0700144BcStatus bc_parse_expr_status(BcParse *p, uint8_t flags, BcParseNext next);
Gavin Howardff66e292018-03-28 12:47:58 -0600145
Gavin Howard10667092018-12-20 11:52:55 -0700146#if BC_ENABLE_SIGNALS
147extern const char bc_sig_msg[];
Gavin Howard10667092018-12-20 11:52:55 -0700148#endif // BC_ENABLE_SIGNALS
149
Gavin Howarda73c11b2018-12-17 11:30:39 -0700150extern const char* const bc_parse_const1;
Gavin Howard675b5cc2018-12-20 16:55:36 -0700151extern const uint8_t bc_parse_exprs[];
Gavin Howardc1902aa2018-12-20 15:54:28 -0700152extern const uchar bc_parse_ops[];
Gavin Howardf89006a2018-10-29 13:01:51 -0600153extern const BcParseNext bc_parse_next_expr;
154extern const BcParseNext bc_parse_next_param;
155extern const BcParseNext bc_parse_next_print;
156extern const BcParseNext bc_parse_next_rel;
157extern const BcParseNext bc_parse_next_elem;
158extern const BcParseNext bc_parse_next_for;
159extern const BcParseNext bc_parse_next_read;
160
Gavin Howarddf4fe792018-10-03 16:48:30 -0600161#endif // BC_ENABLED
162
Gavin Howard4ffe5a92018-09-26 20:58:31 -0600163#endif // BC_BC_H