add unfinished bmpImage implementation
[openc2e.git] / token.h
blob3b6426e07342df6129fb0f7296c79da2aff5f226
1 /*
2 * token.h
3 * openc2e
5 * Created by Bryan Donlan on Thu 11 Aug 2005.
6 * Copyright (c) 2005 Bryan Donlan. All rights reserved.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
19 #ifndef TOKEN_H
20 #define TOKEN_H 1
22 #include "openc2e.h"
23 #include "caosVar.h"
24 #include "exceptions.h"
25 #include <vector>
26 #include <iostream>
27 #include <sstream>
28 #include <boost/variant.hpp>
29 #include <boost/format.hpp>
31 void yyrestart(std::istream *stream, bool use_c2);
33 enum toktype { ANYTOKEN = 0, EOI = 0, TOK_CONST, TOK_WORD, TOK_BYTESTR };
36 struct token {
37 struct token_eoi { };
38 struct type_visitor : public boost::static_visitor<toktype> {
39 toktype operator()(const token_eoi) const { return EOI; }
40 toktype operator()(const caosVar &) const { return TOK_CONST; }
41 toktype operator()(const std::string &) const { return TOK_WORD; }
42 toktype operator()(const bytestring_t &) const { return TOK_BYTESTR; }
44 struct dump_visitor : public boost::static_visitor<std::string> {
45 std::string operator()(const token_eoi) const { return std::string("EOI"); }
46 std::string operator()(const caosVar &v) const { return std::string(v.dump()); }
47 std::string operator()(const std::string &v) const { return v; }
48 std::string operator()(const bytestring_t &bs) const {
49 std::ostringstream oss;
50 oss << "[ ";
51 for (size_t i = 0; i < bs.size(); i++)
52 oss << bs[i] << " ";
53 oss << "]";
54 return oss.str();
57 struct fmt_visitor : boost::static_visitor<std::string> {
58 std::string operator()(const token_eoi) const { return std::string("<EOI>"); }
59 std::string operator()(const caosVar &v) const {
60 if (v.hasInt()) {
61 return boost::str(boost::format("%d") % v.getInt());
62 } else if (v.hasFloat()) {
63 return boost::str(boost::format("%f") % v.getFloat());
64 } else if (v.hasString()) {
65 std::ostringstream outbuf;
66 std::string inbuf = v.getString();
67 outbuf << '"';
68 for (size_t i = 0; i < inbuf.size(); i++) {
69 switch (inbuf[i]) {
70 case '\n': outbuf << "\\\n"; break;
71 case '\r': outbuf << "\\\r"; break;
72 case '\t': outbuf << "\\\t"; break;
73 case '\"': outbuf << "\\\""; break;
74 default: outbuf << inbuf[i]; break;
77 outbuf << '"';
78 return outbuf.str();
79 } else {
80 throw creaturesException(std::string("Impossible caosvar type in token: ") + v.dump());
83 std::string operator()(const std::string &word) const { return word; }
84 std::string operator()(const bytestring_t &bs) const {
85 std::ostringstream oss;
86 oss << "[ ";
87 for (size_t i = 0; i < bs.size(); i++)
88 oss << i << " ";
89 oss << "]";
90 return oss.str();
97 boost::variant<token_eoi, std::string, caosVar, bytestring_t> payload;
99 int index;
100 int lineno;
102 toktype type() const {
103 return boost::apply_visitor(type_visitor(), payload);
106 const bytestring_t &bytestr() const {
107 const bytestring_t *bs = boost::get<bytestring_t>(&payload);
108 if (!bs) unexpected();
109 return *bs;
112 const std::string &word() const {
113 const std::string *s = boost::get<std::string>(&payload);
114 if (!s) unexpected();
115 return *s;
118 const caosVar &constval() const {
119 const caosVar *s = boost::get<caosVar>(&payload);
120 if (!s) unexpected();
121 return *s;
123 token() {}
124 token(const token &cp) : payload(cp.payload), index(cp.index), lineno(cp.lineno) { }
125 token(const caosVar &cv, int lineno_) : payload(cv), index(-1), lineno(lineno_) {}
126 token(const std::string &word, int lineno_) : payload(word), index(-1), lineno(lineno_) {}
127 token(const bytestring_t &bs, int lineno_) : payload(bs), index(-1), lineno(lineno_) {}
129 std::string dump() const {
130 std::ostringstream oss;
131 oss << boost::apply_visitor(dump_visitor(), payload);
132 oss << " (line " << lineno << ")";
133 return oss.str();
136 std::string format() const {
137 return boost::apply_visitor(fmt_visitor(), payload);
140 void unexpected() const {
141 const char *err;
142 switch (type()) {
143 case EOI: err = "EOI"; break;
144 case TOK_WORD: err = "word"; break;
145 case TOK_BYTESTR: err = "bytestring"; break;
146 case TOK_CONST: err = "constant value"; break;
147 default: throw creaturesException("Internal error: unable to classify token in token::unexpected()");
150 throw parseException(std::string("Unexpected ") + err);
154 extern token lasttok; // internal use only
156 #endif
158 /* vim: set noet: */