Commits

Lenard Lindstrom committed 9184449

Start on the parser's scanner

To help in later development, the first stage of development is a blit code to
jit code compiler. This will help in debugging the high level blit routines,
such as alpha blit, to be implemented later.

Language tokens are white space separated strings.

Comments (0)

Files changed (5)

 
   g++ -std=c++98 -g -Iinclude test/testmemory.cpp src/memory.cpp -o testmemory
 
+Source Language
+---------------
 
+The ImgBlit source language operates on array types. A blit operation is a
+function that takes zero or more source array arguments and returns the
+target array value. Arguments are passed by value. The target array may be
+one of the source arguments. Altering it does not affect the actual target
+of the operation.
+
+A blit function is written in an abstract assembly language. Each instruction
+is an operation with zero or more arguments. The language is procedural.
+Instructions modify local array variables. For a binary operation, the first
+argument is applied to the second. Several global values, registers, may be
+available. Additional local variables can be defined.
+
+Language tokens are white space separated.

include/imgblit/parser.h

+#ifndef IMGBLIT_PARSER_H
+#define IMGBLIT_PARSER_H
+
+#include "scanner.h"
+
+namespace imgblit {
+    class Parser {
+
+    public:
+        Parser(Scanner &source);
+        virtual ~Parser();
+        Reference parse();
+    protected:
+        Scanner &psr_source;
+    private:
+        Parser();
+        Parser(const Parser &);
+        Parser & operator=(const Parser &);
+    };
+};
+
+#endif

include/imgblit/scanner.h

+#ifndef IMGBLIT_SCANNER_H
+#define IMGBLIT_SCANNER_H
+
+#include "memory.h"
+#include <string>
+#include <vector>
+#include <ostream>
+
+using std::string;
+using std::ostream;
+using std::vector;
+
+namespace imgblit {
+    struct token_t;
+
+    class Token : public Reference {
+
+    public:
+        Token() { }
+        Token(const string &source,
+              string::size_type lexeme_start,
+              string::size_type lexeme_size,
+              const char *token_class);
+    protected:
+        token_t *get_token_p() const;
+    };
+
+
+    class Scanner {
+    
+    public:
+        Scanner(const char *source);
+        virtual ~Scanner();
+        virtual void reset();
+        Token get_token();
+        void push_back_token(const Token t);
+    protected:
+        Token read_token();
+        string scr_source;
+        vector<Token> scr_next;
+        string::size_type scr_read_start;
+    private:
+        Scanner();
+        Scanner(const Scanner &);
+        Scanner & operator=(const Scanner &);
+    };
+
+    class Parser {
+
+    public:
+        Parser(Scanner &source);
+        virtual ~Parser();
+        Reference parse();
+    protected:
+        Scanner &psr_source;
+    private:
+        Parser();
+        Parser(const Parser &);
+        Parser & operator=(const Parser &);
+    };
+};
+
+#endif
+#include "imgblit/scanner.h"
+#include "imgblit/internal.h"
+#include <ostream>
+
+using std::ostream;
+
+namespace imgblit {
+    struct token_t : public datum_t {
+        token_t(const string &source,
+                string::size_type lexeme_start,
+                string::size_type lexeme_size,
+                const char *token_class) :
+            tk_lexeme(source, lexeme_start, lexeme_size),
+            tk_class(not_null_guard(token_class)) { }
+        const char * const tk_class;
+        const string tk_lexeme;
+        void write(ostream &os) const;
+    private:
+        token_t();
+        token_t(const token_t &);
+        token_t &operator =(const token_t&);
+    };
+
+    void
+    token_t::write(ostream &os) const
+    {
+        os << "Token(\"" << tk_lexeme << "\"" << ", \"" << tk_class << "\")";
+    }
+};
+
+using namespace imgblit;
+
+Token::Token(const string &source,
+             string::size_type lexeme_start,
+             string::size_type lexeme_size,
+             const char *token_class) :
+    Reference(new token_t(source,
+                          lexeme_start,
+                          lexeme_size,
+                          token_class))
+{
+}
+
+token_t *
+Token::get_token_p() const
+{
+    return not_null_guard(dynamic_cast<token_t *>(get_datum_p()));
+}
+
+Scanner::Scanner(const char *source) :
+    scr_source(source), scr_read_start(0)
+{
+    push_back_token(read_token());
+}
+
+Scanner::~Scanner()
+{
+}
+
+void
+Scanner::reset()
+{
+    scr_read_start = 0;
+    scr_next.clear();
+    scr_next.push_back(read_token());
+}
+
+Token
+Scanner::get_token()
+{
+    Token t = scr_next.back();
+    scr_next.pop_back();
+    if (scr_next.empty()) {
+        scr_next.push_back(read_token());
+    }
+    return t;
+}
+
+void
+Scanner::push_back_token(const Token t)
+{
+    scr_next.push_back(t);
+}
+
+Token
+Scanner::read_token()
+{
+    const char * const token_class = "token";
+    string::size_type end = scr_source.size();
+    string::size_type i = scr_read_start;
+
+    while (i != end && isspace(scr_source[i])) {
+        ++i;
+    }
+    scr_read_start = i;
+    if (i == end) {
+        return Token();
+    }
+    while (scr_read_start != end &&
+           !isspace(scr_source[scr_read_start])) {
+        ++scr_read_start;
+    }
+    return Token(scr_source, i, scr_read_start - i, token_class);
+}
+
+Parser::Parser(Scanner &source) : psr_source(source)
+{
+}
+
+Parser::~Parser()
+{
+}
+
+Reference
+Parser::parse()
+{
+    return Reference();
+}

test/testscanner.cpp

+#include "imgblit/scanner.h"
+#include <sstream>
+#include <cassert>
+
+using namespace imgblit;
+using std::stringstream;
+
+int main()
+{
+    Scanner scan("one two three");
+    Token t_one = scan.get_token();
+    Token t_two = scan.get_token();
+    Token t_three = scan.get_token();
+    Token t_none = scan.get_token();
+    stringstream capture;
+
+    // Three tokens are returned. The fourth is the non reference.
+    capture << static_cast<bool>(t_one) << static_cast<bool>(t_two)
+	    << static_cast<bool>(t_three) << static_cast<bool>(t_none);
+    assert(capture.str() == "1110");
+
+    // The token lexems are "one", "two", and "three".
+    capture.str("");
+    capture << t_one << t_two << t_three;
+    assert(capture.str() == ("Token(\"one\", \"token\")"
+			     "Token(\"two\", \"token\")"
+			     "Token(\"three\", \"token\")"));
+
+    // Go back to the beginning of the source string.
+    capture.str("");
+    scan.reset();
+    Token t_reset_one = scan.get_token();
+    Token t_reset_two = scan.get_token();
+    Token t_reset_three = scan.get_token();
+    Token t_reset_none = scan.get_token();
+    capture << t_reset_one << t_reset_two << t_reset_three << t_reset_none;
+    assert(capture.str() == ("Token(\"one\", \"token\")"
+			     "Token(\"two\", \"token\")"
+			     "Token(\"three\", \"token\")"			
+			     "Reference()"));
+
+    return 0;
+}