]> git.mdlowis.com Git - proto/sclpl.git/commitdiff
finished number matching
authorMike D. Lowis <mike@mdlowis.com>
Tue, 26 Feb 2013 23:56:53 +0000 (18:56 -0500)
committerMike D. Lowis <mike@mdlowis.com>
Tue, 26 Feb 2013 23:56:53 +0000 (18:56 -0500)
source/lexer/classes.c
source/lexer/classes.h
source/lexer/lex.c
source/lexer/lex.h

index a57ad6651cb0e129b7a4a5ef714f52f056969098..4e088df1f0353e1bd62b847f40b13898b7842f78 100644 (file)
@@ -30,7 +30,7 @@ bool hex_digit(void)
 
 bool token_end(void)
 {
-    return (whitespace() || file_eof());
+    return (whitespace() || matches_any("()[]{};") || file_eof());
 }
 
 bool matches(char ch)
index 25ee730c70e6fcc34a173c3b8cd495dd05bb6a56..cb935dee052ae059bb36dc42c756691c94228a93 100644 (file)
@@ -9,11 +9,14 @@
 
 #include <stdbool.h>
 
+typedef bool (*predicate_t)(void);
+
 bool whitespace(void);
 bool digit(void);
 bool hex_digit(void);
 bool token_end(void);
 bool matches(char ch);
 bool matches_any(char* str);
+bool one_or_more(predicate_t pfn);
 
 #endif /* CLASSES_H */
index 999cb49a96a5a146113377b462a3d7867b83e28f..9cc160caa54a2d9e8bcd993916301d82734ce197 100644 (file)
@@ -5,13 +5,16 @@
     $HeadURL$
 */
 #include <string.h>
+#include <setjmp.h>
 #include "lex.h"
 #include "classes.h"
 #include "file.h"
 #include "buf.h"
 
-tok_t Token = { 0u };
-
+/* Global Variables
+ *****************************************************************************/
+tok_t Token;
+jmp_buf Jump_Point;
 const char* Token_Strings[TOK_MAX] = {
     "EOF",    /* TOK_EOF */
     "ID",     /* TOK_ID  */
@@ -25,21 +28,91 @@ const char* Token_Strings[TOK_MAX] = {
     "TERM",   /* TOK_TERM */
 };
 
+/* Control Functions
+ *****************************************************************************/
+void record_position(void)
+{
+    Token.line   = file_line();
+    Token.column = file_column();
+}
+
+void set_type(tok_type_t type)
+{
+    Token.type = Token_Strings[type];
+}
+
+void consume(void)
+{
+    buf_put( file_get() );
+}
+
+void match_consume(char ch)
+{
+    if (matches(ch))
+        consume();
+    else
+        abort();
+}
+
+void prepare_for_token(void)
+{
+    (void)memset(&Token,0,sizeof(Token));
+    while( whitespace() )
+        (void)file_get();
+    record_position();
+}
+
+void accept_char(tok_type_t type)
+{
+    set_type(type);
+    consume();
+    accept();
+}
+
+void accept(void)
+{
+    if (!token_end())
+        abort();
+    else
+        Token.str = buf_accept();
+}
+
+void abort(void)
+{
+    longjmp(Jump_Point,1);
+}
+
+bool one_or_more(predicate_t pfn)
+{
+    if (!pfn()) abort();
+    while (pfn()) consume();
+}
+
+/* Token Matching Functions
+ *****************************************************************************/
 tok_t next_token(void)
 {
     prepare_for_token();
     if (!file_eof())
     {
-        if (matches_any("()[]{};"))
-            punctuation();
-        else if (digit())
-            number();
-        //else if (matches('\''))
-        //    character();
-        //else if (matches('\"'))
-        //    string();
+        /* Mark our starting point so we can resume if we abort */
+        if (0 == setjmp(Jump_Point))
+        {
+            if (matches_any("()[]{};"))
+                punctuation();
+            else if (matches('-') || digit() || matches('h'))
+                number();
+            //else if (matches('\''))
+            //    character();
+            //else if (matches('\"'))
+            //    string();
+            else
+                identifier();
+        }
         else
+        {
             identifier();
+        }
 
         /* the keyword "end" is actually a TOK_TERM */
         if (0 == strcmp(Token.str,"end"))
@@ -63,58 +136,47 @@ void punctuation(void)
     }
 }
 
-void number()
+void number(void)
 {
     set_type(TOK_NUM);
-
-    while (digit()) consume();
-
-    if (!token_end())
-        identifier();
+    if (matches('h'))
+    {
+        hexadecimal();
+    }
     else
-        accept();
-}
-
-void identifier()
-{
-    set_type(TOK_ID);
-    while (!token_end() && !matches_any("()[]{};")) consume();
+    {
+        floating_point();
+        if (matches_any("eE"))
+        {
+            consume();
+            floating_point();
+        }
+    }
     accept();
 }
 
-void record_position(void)
-{
-    Token.line   = file_line();
-    Token.column = file_column();
-}
-
-void set_type(tok_type_t type)
+void hexadecimal(void)
 {
-    Token.type = Token_Strings[type];
+    match_consume('h');
+    one_or_more( hex_digit );
 }
 
-void consume(void)
+void floating_point(void)
 {
-    buf_put( file_get() );
-}
-
-void prepare_for_token(void)
-{
-    (void)memset(&Token,0,sizeof(Token));
-    while( whitespace() )
-        (void)file_get();
-    record_position();
+    if (matches('-')) consume();
+    one_or_more( digit );
+    if (matches('.'))
+    {
+        consume();
+        one_or_more( digit );
+    }
 }
 
-void accept_char(tok_type_t type)
+void identifier(void)
 {
-    set_type(type);
-    consume();
+    set_type(TOK_ID);
+    while (!token_end())
+        consume();
     accept();
 }
 
-void accept()
-{
-    Token.str = buf_accept();
-}
-
index a85e61ae33dd0acb645f00faaa34c4f092041725..5bfd45a135045a2b346e6ce276f093c5b74a8f5e 100644 (file)
@@ -7,6 +7,8 @@
 #ifndef LEX_H
 #define LEX_H
 
+#include "classes.h"
+
 typedef struct
 {
     int line;
@@ -34,10 +36,15 @@ void punctuation(void);
 void record_position(void);
 void identifier(void);
 void number(void);
+void hexadecimal(void);
+void floating_point(void);
 void set_type(tok_type_t type);
 void consume(void);
+void match_consume(char ch);
 void prepare_for_token(void);
 void accept_char(tok_type_t type);
 void accept(void);
+void abort(void);
+bool one_or_more(predicate_t pfn);
 
 #endif /* LEX_H */