Author | Jamozed <[email protected]> |
Date | 2021-09-11 06:15:34 |
Commit | 30bbeefe64d845ddc2dadda0fbe7dac5aed33a01 |
Parent | 99a3dff6f85c984a3d2e7b5de49763dfa2d58396 |
Reimplement compound statements
Diffstat
M | src/bltn.c | | | 5 | ++--- |
D | src/cll/cll.h | | | 98 | -------------------------------------------------------------------------------- |
M | src/esh.h | | | 9 | +++++---- |
M | src/exec.c | | | 42 | +++++++++++++++++++++++++----------------- |
D | src/exec.h | | | 38 | -------------------------------------- |
M | src/lex.c | | | 5 | ++--- |
M | src/lineread.c | | | 2 | +- |
M | src/lineread.h | | | 2 | +- |
M | src/main.c | | | 5 | ++--- |
M | src/parse.c | | | 76 | ++++++++++++++++++++++++++++++++++++++++++++++------------------------------ |
M | src/util/array.c | | | 30 | +++++++++++++----------------- |
M | src/util/array.h | | | 6 | ++---- |
M | src/util/util.h | | | 4 | +--- |
13 files changed, 100 insertions, 222 deletions
diff --git a/src/bltn.c b/src/bltn.c index 708429a..f5d8688 100644 --- a/src/bltn.c +++ b/src/bltn.c @@ -33,14 +33,13 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE. #include "alias.h" #include "bltn.h" #include "esh.h" -#include "exec.h" #include "cll/error.h" #include "cll/optget.h" #include <stdio.h> -static int bltn_eval(char *av[]) { return execute__(&av[1]); } +static int bltn_eval(char *av[]) { warn("eval: Unimplemented"); return -1; } static int bltn_exit(char *av[]) { (void)(av); _loop = 0; return 0; } static int bltn_false(char *av[]) { (void)(av); return 1; } static int bltn_help(char *av[]); @@ -50,7 +49,7 @@ extern int bltn_cd(char *av[]); extern int bltn_pwd(char *av[]); extern int bltn_set(char *av[]); -static int getret(char *av[]) { printf("%d\n", _ret); return 0; } +static int getret(char *av[]) { printf("%i\n", _ret); return 0; } struct bltn bltns[] = { {"alias", &bltn_alias}, diff --git a/src/cll/cll.h b/src/cll/cll.h deleted file mode 100644 index 8adf5b1..0000000 --- a/src/cll/cll.h +++ /dev/null @@ -1,98 +0,0 @@ -// cll.h -// cll header file for cll -// Copyright (C) 2021, Jakob Wakeling -// All rights reserved. - -/* -OMKOV Permissive Licence, version 1.0 - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal with -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimers. -* Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimers in the documentation and/or - other materials provided with the distribution. -* Neither the names of the copyright holders, nor the names of its contributors - may be used to endorse or promote products derived from this Software without - specific prior written permission. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT -HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE. -*/ - -#ifndef OMKOV_CLL_CLL_H_ZO7IRBJS -#define OMKOV_CLL_CLL_H_ZO7IRBJS - -#include <float.h> -#include <stdbool.h> -#include <stddef.h> -#include <stdint.h> - -typedef void *ptr; - -typedef uint8_t u8; -typedef uint16_t u16; -typedef uint32_t u32; -typedef uint64_t u64; -typedef uintptr_t uint_; - -#define UINT uint_ - -typedef int8_t s8; -typedef int16_t s16; -typedef int32_t s32; -typedef int64_t s64; -typedef intptr_t sint; - -typedef float f32; -typedef double f64; -typedef long double f128; - -#define U8_MIN UINT8_MIN -#define U8_MAX UINT8_MAX -#define U16_MIN UINT16_MIN -#define U16_MAX UINT16_MAX -#define U32_MIN UINT32_MIN -#define U32_MAX UINT32_MAX -#define U64_MIN UINT64_MIN -#define U64_MAX UINT64_MAX -#define UINT_MIN UINTPTR_MIN -#define UINT_MAX UINTPTR_MAX - -#define S8_MIN INT8_MIN -#define S8_MAX INT8_MAX -#define S16_MIN INT16_MIN -#define S16_MAX INT16_MAX -#define S32_MIN INT32_MIN -#define S32_MAX INT32_MAX -#define S64_MIN INT64_MIN -#define S64_MAX INT64_MAX -#define SINT_MIN INTPTR_MIN -#define SINT_MAX INTPTR_MAX - -#define F32_MIN FLT_MIN -#define F32_MAX FLT_MAX -#define F64_MIN DBL_MIN -#define F64_MAX DBL_MAX -#define F128_MIN LDBL_MIN -#define F128_MAX LDBL_MAX - -#define BIT(x) (1 << (x)) - -#define IS_BIN(c) (c == '0' || c == '1') -#define IS_OCT(c) (c >= '0' && c <= '7') -#define IS_DEC(c) (c >= '0' && c <= '9') -#define IS_DOZ(c) ((c >= '0' && c <= '9') || (c == 'A' || c == 'B')) -#define IS_HEX(c) ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F')) - -#endif // OMKOV_CLL_CLL_H_ZO7IRBJS diff --git a/src/esh.h b/src/esh.h index d62f33d..86d0dd9 100644 --- a/src/esh.h +++ b/src/esh.h @@ -33,19 +33,20 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE. #ifndef ESH_ESH_H_SAZDXXFN #define ESH_ESH_H_SAZDXXFN -#include "cll/cll.h" +#include "util/array.h" +#include "util/util.h" typedef enum { - LK_NIL, LK_EOF, LK_WORD, LK_END, + LK_NULL, LK_EOF, LK_WORD, LK_END, LK_PIPE, LK_RDIN, LK_ROUT, LK_RERR, } tok_k; -typedef enum { AK_NIL, AK_COM } ast_k; +typedef enum { AK_NULL, AK_COMP, AK_COMM } ast_k; typedef struct { tok_k k; u8 *s; } tok; typedef struct { u8 *s; UINT sp, sl; tok t; } lex; -typedef struct ast { ast_k k; u8 *s, **a; UINT al; struct ast *c; } ast; +typedef struct { ast_k k; u8 *s; array c; } ast; extern int _loop, _ret; diff --git a/src/exec.c b/src/exec.c index 9af7135..7e42746 100644 --- a/src/exec.c +++ b/src/exec.c @@ -32,7 +32,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE. #include "bltn.h" #include "esh.h" -#include "exec.h" #include "cll/error.h" @@ -45,19 +44,40 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE. #include <stdlib.h> #include <string.h> +static int execute_comp(ast *a); +static int execute_comm(ast *a); + static int launch(u8 *av[]); /* Execute a program. */ int execute(ast *a) { - /* TODO dont assume that the ast is a command */ + switch (a->k) { + case AK_COMP: { return execute_comp(a); } + case AK_COMM: { return execute_comm(a); } + default: { error(-1, "%s: Unimplemented AST", ast_ks[a->k]); } + } +} + +/* Execute a compound statement. */ +static int execute_comp(ast *a) { + register int ret = 0; + for (UINT i = 0; i != a->c->size; i += 1) { + ret = execute(a->c->data[i]); + } + + return ret; +} + +/* Execute a command statement. */ +static int execute_comm(ast *a) { if (!a->s) { return _ret; } /* What does this achieve? */ for (struct bltn *b = bltns; b->s; b += 1) { - if (strcmp((char *)a->s, b->s) == 0) { return b->f((char **)a->a); } + if (strcmp((char *)a->s, b->s) == 0) { return b->f((char **)a->c->data); } } - return launch(a->a); + return launch((u8 **)a->c->data); } /* Fork and execute an executable. */ @@ -75,17 +95,5 @@ static int launch(u8 *av[]) { else if (pid == -1) { perror((char *)av[0]); } else { waitpid(pid, &status, 0); } - return WEXITSTATUS(status); -} - -/* -------------------------------------------------------------------------- */ - -int execute__(char *av[]) { - if (!av[0]) { return _ret; } - - for (struct bltn *b = bltns; b->s; ++b) { - if (strcmp(av[0], b->s) == 0) { return b->f(av); } - } - - return launch((u8 **)av); + return status; } diff --git a/src/exec.h b/src/exec.h deleted file mode 100644 index 6c0f343..0000000 --- a/src/exec.h +++ /dev/null @@ -1,38 +0,0 @@ -// exec.h -// Exec header file for ESH -// Copyright (C) 2020, Jakob Wakeling -// All rights reserved. - -/* -OMKOV Permissive Licence, version 1.0 - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal with -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimers. -* Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimers in the documentation and/or - other materials provided with the distribution. -* Neither the names of the copyright holders, nor the names of its contributors - may be used to endorse or promote products derived from this Software without - specific prior written permission. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT -HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE. -*/ - -#ifndef OMKOV_ESH_EXEC_H_VI5E8LVV -#define OMKOV_ESH_EXEC_H_VI5E8LVV - -extern int execute__(char *argv[]); - -#endif // OMKOV_ESH_EXEC_H_VI5E8LVV diff --git a/src/lex.c b/src/lex.c index 202c072..60315e3 100644 --- a/src/lex.c +++ b/src/lex.c @@ -31,8 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE. */ #include "esh.h" - -#include "cll/cll.h" +#include "util/util.h" #include <ctype.h> #include <stdio.h> @@ -43,7 +42,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE. #define D (l->s[l->sp + 1]) u8 *tok_ks[] = { - (u8 *)"NIL", (u8 *)"EOF", (u8 *)"WORD", (u8 *)"END", + (u8 *)"NULL", (u8 *)"EOF", (u8 *)"WORD", (u8 *)"END", (u8 *)"PIPE", (u8 *)"RDIN", (u8 *)"ROUT", (u8 *)"RERR", }; diff --git a/src/lineread.c b/src/lineread.c index e80a3a2..0489df6 100644 --- a/src/lineread.c +++ b/src/lineread.c @@ -32,8 +32,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE. #include "conf.h" #include "lineread.h" +#include "util/util.h" -#include "cll/cll.h" #include "cll/error.h" #include <sys/ioctl.h> diff --git a/src/lineread.h b/src/lineread.h index c8406e1..7acab8a 100644 --- a/src/lineread.h +++ b/src/lineread.h @@ -33,7 +33,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE. #ifndef OMKOV_ESH_LINEREAD_H_RPVXY3N7 #define OMKOV_ESH_LINEREAD_H_RPVXY3N7 -#include "cll/cll.h" +#include "util/util.h" extern u8 *lineread(void); extern void linefree(void); diff --git a/src/main.c b/src/main.c index 1057399..ee6bfb1 100644 --- a/src/main.c +++ b/src/main.c @@ -31,10 +31,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE. */ #include "esh.h" -#include "exec.h" #include "lineread.h" +#include "util/util.h" -#include "cll/cll.h" #include "cll/error.h" #include "cll/optget.h" @@ -88,7 +87,7 @@ int main(int ac, char *av[]) { (void)(ac); A0 = av[0]; ast *a = parse(&l); if (!a) { goto loop; } if (Pflag) { ast_debug(a); goto loop; } - _ret = execute(a); + _ret = WEXITSTATUS(execute(a)); loop:; ast_free(a); free(line); diff --git a/src/parse.c b/src/parse.c index a327ab3..46900c4 100644 --- a/src/parse.c +++ b/src/parse.c @@ -31,52 +31,57 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE. */ #include "esh.h" +#include "util/llist.h" +#include "util/util.h" -#include "cll/cll.h" +#include "cll/error.h" #include <stdio.h> #include <stdlib.h> -typedef struct { u8 **a; UINT al; } arr; +u8 *ast_ks[] = { (u8 *)"NULL", (u8 *)"COMP", (u8 *)"COMM" }; -static const arr ARR_INIT = { NULL, 0 }; +static ast *parse_comp(lex *l); +static ast *parse_comm(lex *l); -u8 *ast_ks[] = { (u8 *)"NIL", (u8 *)"COM" }; - -static void arr_push(arr *a, u8 *s); - -static ast *parse_com(lex *l); - -ast *ast_init(void) { return calloc(1, sizeof (ast)); } +/* Initialise an AST node. */ +ast *ast_init(void) { + return assert_calloc(1, sizeof (ast)); +} +/* Uninitialise an AST node. */ void ast_free(ast *a) { - for (; a->al; a->al -= 1) { free(a->a[a->al - 1]); } - free(a->a); free(a); + if (a) { array_free(a->c); free(a); } } /* Parse a program. */ ast *parse(lex *l) { if (lex_peek(l).k == LK_EOF) { return NULL; } - /* TODO handle compound commands */ - return parse_com(l); + return parse_comp(l); } -/* Parse a command. */ -static ast *parse_com(lex *l) { - ast *a = ast_init(); arr av = ARR_INIT; - a->k = AK_COM; arr_push(&av, a->s = lex_next(l).s); +/* Parse a comound statement. */ +static ast *parse_comp(lex *l) { + ast *a = ast_init(); a->k = AK_COMP; + a->c = array_init((void (*)(ptr))&ast_free); - /* Push each of the command arguments onto the array */ - for (tok t; (t = lex_next(l)).k == LK_WORD;) { arr_push(&av, t.s); } + /* Push each command onto the array */ + for (; lex_peek(l).k != LK_EOF;) { array_push(a->c, parse_comm(l)); } - a->al = av.al; arr_push(&av, NULL); a->a = av.a; return a; + return a; } -/* Push a string to the end of an array. */ -void arr_push(arr *a, u8 *s) { - a->a = realloc(a->a, (a->al += 1) * sizeof (*a->a)); - a->a[a->al - 1] = s; +/* Parse a command statement. */ +static ast *parse_comm(lex *l) { + ast *a = ast_init(); a->k = AK_COMM; + a->c = array_init(NULL); + + /* Push each command argument onto the array. */ + array_push(a->c, (a->s = lex_next(l).s)); + for (tok t; (t = lex_next(l)).k == LK_WORD;) { array_push(a->c, t.s); } + + array_push(a->c, NULL); return a; } /* Print parser debug output with an indent. */ @@ -84,11 +89,22 @@ static void ast_debug_indent(ast *a, UINT i) { for (UINT j = 0; j != i; ++j) { printf("\t"); } printf("%s: %s", ast_ks[a->k], a->s); - /* Print command arguments if present. */ - for (UINT i = 0; i != a->al; i += 1) { printf(" %s", a->a[i]); } - printf("\n"); - - if (a->c) { ast_debug_indent(a->c, i + 1); } + /* Print children if present. */ + switch (a->k) { + case AK_COMP: { + printf("\n"); + for (UINT j = 0; j != a->c->size; j += 1) { + ast_debug_indent(a->c->data[j], i + 1); + printf("\n"); + } + } break; + case AK_COMM: { + for (UINT j = 0; j != a->c->size - 1; j += 1) { + printf(" %s", (u8 *)a->c->data[j]); + } + } break; + default: { warn("%s: Unimplemented AST (debug)", ast_ks[a->k]); } break; + } } /* Print parser debug output. */ diff --git a/src/util/array.c b/src/util/array.c index b708190..45f0a8d 100644 --- a/src/util/array.c +++ b/src/util/array.c @@ -36,29 +36,25 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE. #include <stdlib.h> /* Initialise an array. */ -array array_init(void) { - return assert_calloc(1, sizeof (struct array_)); +array array_init(void (*free)(ptr)) { + register array a = assert_calloc(1, sizeof (*a)); + a->free = free; return a; } /* Uninitialise an array. */ -void array_free(array a) { - free(a); +void array_free(array a) { + if (a) { + for (UINT i = 0; i != a->size; i += 1) { + if (a->free) { a->free(a->data[i]); } + else { free(a->data[i]); } + } + + free(a->data); free(a); + } } /* Push a pointer to an array. */ void array_push(array a, ptr data) { - a->data = assert_realloc(a->data, (a->size += 1)); + a->data = assert_realloc(a->data, (a->size += 1) * sizeof (*a->data)); a->data[a->size - 1] = data; } - -/* Pop a pointer from an array. */ -ptr array_pop(array a) { - ptr data = a->data[a->size - 1]; - a->data = assert_realloc(a->data, (a->size -= 1)); - return data; -} - -/* Peek at a pointer on an array without popping. */ -ptr array_peek(array a) { - return a->data[a->size - 1]; -} diff --git a/src/util/array.h b/src/util/array.h index afce368..736bd53 100644 --- a/src/util/array.h +++ b/src/util/array.h @@ -37,13 +37,11 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE. typedef struct array_ *array; -struct array_ { ptr *data; UINT size; }; +struct array_ { ptr *data; UINT size; void (*free)(ptr); }; -extern array array_init(void); +extern array array_init(void (*free)(ptr)); extern void array_free(array a); extern void array_push(array a, ptr data); -extern ptr array_pop(array a); -extern ptr array_peek(array a); #endif // ESH_UTIL_ARRAY_H_9LJ2QOUZ diff --git a/src/util/util.h b/src/util/util.h index 1a8dbb2..3e9c772 100644 --- a/src/util/util.h +++ b/src/util/util.h @@ -42,9 +42,7 @@ typedef uint8_t u8; typedef uint16_t u16; typedef uint32_t u32; typedef uint64_t u64; -typedef uintptr_t uint_; - -#define UINT uint_ +typedef uintptr_t UINT; typedef int8_t s8; typedef int16_t s16;