summaryrefslogtreecommitdiff
path: root/src/core/token.c
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2008-05-15 23:28:07 +0000
committerPaul Buetow <paul@buetow.org>2008-05-15 23:28:07 +0000
commitbe839900419c7a74c4a46efd279d0ca16b35dc1f (patch)
tree1355c8f238d1c58ffd5cb8803bcc2adf987e79aa /src/core/token.c
parent33c945e58f86267b0d3bdca4c3421155e11eb0d9 (diff)
Moved stuff into trunk.
Diffstat (limited to 'src/core/token.c')
-rw-r--r--src/core/token.c380
1 files changed, 380 insertions, 0 deletions
diff --git a/src/core/token.c b/src/core/token.c
new file mode 100644
index 0000000..1573371
--- /dev/null
+++ b/src/core/token.c
@@ -0,0 +1,380 @@
+/*:*
+ *: File: ./src/core/token.c
+ *: A simple interpreter
+ *:
+ *: WWW : http://fype.buetow.org
+ *: E-Mail : fype@dev.buetow.org
+ *:
+ *: Copyright (c) 2005 2006 2007 2008, Paul Buetow (http://www.pblabs.net)
+ *: All rights reserved.
+ *:
+ *: Redistribution and use in source and binary forms, with or without modi-
+ *: fication, are permitted provided that the following conditions are met:
+ *: * Redistributions of source code must retain the above copyright
+ *: notice, this list of conditions and the following disclaimer.
+ *: * Redistributions in binary form must reproduce the above copyright
+ *: notice, this list of conditions and the following disclaimer in the
+ *: documentation and/or other materials provided with the distribution.
+ *: * Neither the name of P. B. Labs nor the names of its contributors may
+ *: be used to endorse or promote products derived from this software
+ *: without specific prior written permission.
+ *:
+ *: THIS SOFTWARE IS PROVIDED BY Paul Buetow AS IS'' AND ANY EXPRESS OR
+ *: IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *: WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ *: DISCLAIMED. IN NO EVENT SHALL Paul Buetow BE LIABLE FOR ANY DIRECT,
+ *: INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ *: (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ *: SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ *: HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ *: STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ *: IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *: POSSIBILITY OF SUCH DAMAGE.
+ *:*/
+
+#include "token.h"
+
+#include "garbage.h"
+
+#define CHECK(...) if (!strcmp(c_token, __VA_ARGS__)) return
+
+long TOKEN_ID_COUNTER = 0;
+
+TokenType
+get_tt(char *c_token) {
+ CHECK("if") TT_IF;
+ CHECK("ifnot") TT_IFNOT;
+ CHECK("else") TT_ELSE;
+ CHECK("break") TT_BREAK;
+ CHECK("while") TT_WHILE;
+ CHECK("until") TT_UNTIL;
+ CHECK("int") TT_INT;
+ CHECK("next") TT_NEXT;
+ CHECK("defined") TT_DEFINED;
+ CHECK("undef") TT_UNDEF;
+ CHECK("ret") TT_RET;
+ CHECK("const") TT_CONST;
+ CHECK("proc") TT_PROC;
+ CHECK("func") TT_FUNC;
+ CHECK("my") TT_MY;
+ CHECK("not") TT_NOT;
+ CHECK("!=") TT_NEQ;
+ CHECK("=~") TT_RE;
+ CHECK("(") TT_PARANT_L;
+ CHECK(")") TT_PARANT_R;
+ CHECK("*") TT_MULT;
+ CHECK("+") TT_ADD;
+ CHECK("++") TT_INCR;
+ CHECK(",") TT_COMMA;
+ CHECK("-") TT_SUB;
+ CHECK("--") TT_DECR;
+ CHECK(".") TT_DOT;
+ CHECK("/") TT_DIV;
+ CHECK("\\") TT_VID;
+ CHECK(":") TT_DDOT;
+ CHECK("==") TT_EQ;
+ CHECK(";") TT_SEMICOLON;
+ CHECK("<<") TT_LSHIFT;
+ CHECK(">>") TT_RSHIFT;
+ CHECK("and") TT_AND;
+ CHECK("or") TT_OR;
+ CHECK("xor") TT_XOR;
+ CHECK("=") TT_ASSIGN;
+ CHECK("<") TT_LT;
+ CHECK(">") TT_GT;
+ CHECK(">=") TT_GE;
+ CHECK("<=") TT_LE;
+ CHECK("{") TT_PARANT_CL;
+ CHECK("}") TT_PARANT_CR;
+
+ return TT_NONE;
+}
+
+#define CASE(t,r) case t: return r;
+
+char*
+tt_get_name(TokenType tt_cur) {
+ switch (tt_cur) {
+ CASE(START_TERMINALS, "START_TERMINALS")
+ CASE(START_TYPES, "START_TYPES")
+ CASE(START_NUMERICAL, "START_NUMERICAL")
+ CASE(START_ASSIGNABLES, "START_ASSIGNABLES")
+ CASE(TT_IDENT, "TT_IDENT")
+ CASE(TT_DOUBLE,"TT_DOUBLE")
+ CASE(TT_STRING,"TT_STRING")
+ CASE(TT_INTEGER,"TT_INTEGER")
+ CASE(TT_BOOL,"TT_BOOL")
+ CASE(END_ASSIGNABLES, "END_ASSIGNABLES")
+ CASE(END_NUMERICAL, "END_NUMERICAL")
+ CASE(END_TYPES, "END_TYPES")
+
+ // Keywords
+ CASE(START_KEYWORDS, "START_KEYWORDS")
+ CASE(TT_ELSE,"TT_ELSE")
+ CASE(TT_BREAK,"TT_BREAK")
+ CASE(TT_IF,"TT_IF")
+ CASE(TT_IFNOT,"TT_IFNOT")
+ CASE(TT_RET,"TT_RET")
+ CASE(TT_CONST,"TT_CONST")
+ CASE(TT_PROC,"TT_PROC")
+ CASE(TT_FUNC,"TT_FUNC")
+ CASE(TT_MY,"TT_MY")
+ CASE(TT_WHILE,"TT_WHILE")
+ CASE(TT_UNTIL,"TT_UNTIL")
+ CASE(TT_NEXT,"TT_NEXT")
+ CASE(TT_DEFINED,"TT_DEFINED")
+ CASE(TT_UNDEF,"TT_UNDEF")
+ CASE(TT_INT,"TT_INT")
+ CASE(END_KEYWORDS, "END_KEYWORDS")
+
+ // Braces
+ CASE(START_PARANTS, "START_PARANTS")
+ CASE(TT_PARANT_CL,"TT_PARANT_CL")
+ CASE(TT_PARANT_CR,"TT_PARANT_CR")
+ CASE(TT_PARANT_L,"TT_PARANT_L")
+ CASE(TT_PARANT_R,"TT_PARANT_R")
+ CASE(END_PARANTS, "END_PARANTS")
+
+ // Operators
+ CASE(START_OPERATORS, "START_OPERATORS")
+ CASE(TT_ADD,"TT_ADD")
+ CASE(TT_ASSIGN,"TT_ASSIGN")
+ CASE(TT_COMMA,"TT_COMMA")
+ CASE(TT_DDOT,"TT_DDOT")
+ CASE(TT_DECR,"TT_DECR")
+ CASE(TT_DIV,"TT_DIV")
+ CASE(TT_VID,"TT_VID")
+ CASE(TT_DOT,"TT_DOT")
+ CASE(TT_EQ,"TT_EQ")
+ CASE(TT_LE,"TT_LE")
+ CASE(TT_LT,"TT_LT")
+ CASE(TT_GE,"TT_GE")
+ CASE(TT_GT,"TT_GT")
+ CASE(TT_INCR,"TT_INCR")
+ CASE(TT_LSHIFT,"TT_LSHIFT")
+ CASE(TT_RSHIFT,"TT_RSHIFT")
+ CASE(TT_AND,"TT_AND")
+ CASE(TT_OR,"TT_OR")
+ CASE(TT_XOR,"TT_XOR")
+ CASE(TT_NOT,"TT_NOT")
+ CASE(TT_MULT,"TT_MULT")
+ CASE(TT_NEQ,"TT_NEQ")
+ CASE(TT_RE,"TT_RE")
+ CASE(TT_NOTEQ,"TT_NOTEQ")
+ CASE(TT_SEMICOLON,"TT_SEMICOLON")
+ CASE(TT_SUB,"TT_SUB")
+ CASE(END_OPERATORS, "END_OPERATORS")
+ CASE(END_TERMINALS, "END_TERMINALS")
+
+ // Diverse
+ CASE(TT_NONE,"TT_NONE")
+ CASE(TT_END_OF_CODE,"TT_END_OF_CODE")
+ }
+
+ // Never reach this point
+ return "XXXXXXX";
+}
+
+Token*
+token_new(char *c_val, TokenType tt_cur, int i_line_nr, int i_pos_nr, char *c_filename) {
+ Token *p_token = token_new_dummy();
+
+ p_token->c_val = c_val;
+ p_token->i_val = 0;
+ p_token->d_val = 0;
+ p_token->tt_cur = tt_cur;
+ p_token->i_line_nr = i_line_nr;
+ p_token->i_pos_nr = i_pos_nr;
+ p_token->c_filename = c_filename;
+
+ switch (tt_cur) {
+ case TT_INTEGER:
+ p_token->i_val = atoi(c_val);
+ break;
+ case TT_DOUBLE:
+ {
+ p_token->d_val = atof(c_val);
+ break;
+ }
+ NO_DEFAULT;
+ }
+
+ return p_token;
+}
+
+Token*
+token_new_integer(int i_val) {
+ Token *p_token = token_new_dummy();
+ token_set_tt(p_token, TT_INTEGER);
+ token_set_ival(p_token, i_val);
+
+ return (p_token);
+}
+
+Token*
+token_new_double(double d_val) {
+ Token *p_token = token_new_dummy();
+ token_set_tt(p_token, TT_DOUBLE);
+ token_set_dval(p_token, d_val);
+
+ return (p_token);
+}
+
+Token*
+token_new_string(char *c_val) {
+ Token *p_token = token_new_dummy();
+ token_set_tt(p_token, TT_STRING);
+
+ p_token->c_val = calloc(strlen(c_val)+1, sizeof(char));
+ strcpy(p_token->c_val, c_val);
+
+ return (p_token);
+}
+
+
+Token*
+token_new_(char *c_val, TokenType tt_cur, char *c_filename) {
+ return token_new(c_val, tt_cur, -1, -1, c_filename);
+}
+
+Token*
+token_new_dummy() {
+ Token *p_token = malloc(sizeof(Token));
+
+ p_token->c_val = NULL;
+ p_token->tt_cur = TT_NONE;
+ p_token->i_line_nr = -1;
+ p_token->i_pos_nr = -1;
+ p_token->c_filename = NULL;
+ p_token->u_token_id = TOKEN_ID_COUNTER++;
+ p_token->i_ref_count = 0;
+
+ /* Register the token in the garbage collector */
+ garbage_add_token(p_token);
+
+ return p_token;
+}
+
+Token*
+token_new_copy(Token *p_token) {
+ Token *p_token_copy = malloc(sizeof(Token));
+ p_token->u_token_id = TOKEN_ID_COUNTER++;
+
+ if (p_token_copy == NULL)
+ ERROR("Memory alloc error");
+
+ token_copy_vals(p_token_copy, p_token);
+ p_token_copy->i_ref_count = 0;
+
+ /* Register the token in the garbage collector */
+ garbage_add_token(p_token_copy);
+
+ return (p_token_copy);
+}
+
+void token_copy_vals(Token *p_token_to, Token *p_token_from) {
+ int i_len;
+
+ // TODO: Check against mem leak
+ // if (p_token_to->c_val)
+ // free(p_token_to->c_val);
+
+ if (p_token_from->c_val) {
+ i_len = strlen(p_token_from->c_val);
+ p_token_to->c_val = calloc(i_len+1, sizeof(char));
+ strcpy(p_token_to->c_val, p_token_from->c_val);
+ } else {
+ p_token_to->c_val = NULL;
+ }
+
+ p_token_to->tt_cur = p_token_from->tt_cur;
+ p_token_to->i_val = p_token_from->i_val;
+ p_token_to->d_val = p_token_from->d_val;
+ p_token_to->i_line_nr = p_token_from->i_line_nr;
+ p_token_to->i_pos_nr = p_token_from->i_pos_nr;
+ p_token_to->c_filename = p_token_from->c_filename;
+}
+
+void
+token_delete_cb(void *p_void) {
+ token_delete(p_void);
+}
+
+void
+token_ref_down_cb(void *p_void) {
+ Token *p_token = p_void;
+ token_ref_down(p_token);
+}
+
+void*
+token_copy_cb(void *p_void) {
+ return (token_new_copy(p_void));
+}
+
+void
+token_delete(Token *p_token) {
+ if (token_ref_down(p_token) <= 0) {
+ if (p_token->i_ref_count == 0) {
+#ifdef DEBUG_TOKEN_REFCOUNT
+ printf("Token refcount debug: Token ref count is 0 == %d\n",
+ p_token->i_ref_count);
+#endif /* DEBUG_TOKEN_REFCOUNT */
+ if (p_token->c_val)
+ free(p_token->c_val);
+
+ free(p_token);
+ }
+#ifdef DEBUG_TOKEN_REFCOUNT
+ else {
+ printf("Token refcount debug: Token ref count is 0 > %d\n",
+ p_token->i_ref_count);
+ }
+#endif /* DEBUG_TOKEN_REFCOUNT */
+ }
+#ifdef DEBUG_TOKEN_REFCOUNT
+ else {
+ printf("Token refcount debug: Token ref count is 0 < %d\n",
+ p_token->i_ref_count);
+ }
+#endif /* DEBUG_TOKEN_REFCOUNT */
+}
+
+void
+token_print(Token *p_token) {
+ printf("(id=%05u, line=%05d, pos=%04d, type=%s, val=%s, ival=%d, dval=%f,"
+ " refs=%d)",
+ p_token->u_token_id,
+ p_token->i_line_nr,
+ p_token->i_pos_nr,
+ tt_get_name(p_token->tt_cur),
+ p_token->c_val,
+ p_token->i_val,
+ p_token->d_val,
+ p_token->i_ref_count);
+}
+
+void
+token_print_val(Token *p_token) {
+ TokenType tt = token_get_tt(p_token);
+ switch (tt) {
+ case TT_INTEGER:
+ printf("(%s, %d)", tt_get_name(tt), token_get_ival(p_token));
+ break;
+ case TT_DOUBLE:
+ printf("(%s, %f)", tt_get_name(tt), token_get_dval(p_token));
+ break;
+ case TT_STRING:
+ printf("(%s, %s)", tt_get_name(tt), token_get_val(p_token));
+ break;
+ default:
+ ERROR("Ouups(%s)!", tt_get_name(tt));
+ }
+}
+
+void
+token_print_cb(void *p_void) {
+ Token *p_token = p_void;
+ printf("Token ");
+ token_print(p_token);
+ printf("\n");
+}