From c9bfccc35345ce58fb5774d4b0b6a9868b262c0a Mon Sep 17 00:00:00 2001 From: giorgio Date: Wed, 5 Sep 2012 08:31:30 +0000 Subject: git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@1381061 13f79535-47bb-0310-9956-ffa450edef68 --- .../branches/lightweight-sca/modules/scheme/io.hpp | 239 +++++++++++++++++++++ 1 file changed, 239 insertions(+) create mode 100644 sca-cpp/branches/lightweight-sca/modules/scheme/io.hpp (limited to 'sca-cpp/branches/lightweight-sca/modules/scheme/io.hpp') diff --git a/sca-cpp/branches/lightweight-sca/modules/scheme/io.hpp b/sca-cpp/branches/lightweight-sca/modules/scheme/io.hpp new file mode 100644 index 0000000000..8f9d70e7fe --- /dev/null +++ b/sca-cpp/branches/lightweight-sca/modules/scheme/io.hpp @@ -0,0 +1,239 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/* $Rev$ $Date$ */ + +#ifndef tuscany_scheme_io_hpp +#define tuscany_scheme_io_hpp + +/** + * Script evaluator IO functions. + */ + +#include +#include "stream.hpp" +#include "string.hpp" + +#include "list.hpp" +#include "value.hpp" +#include "primitive.hpp" + +namespace tuscany { +namespace scheme { + +const value rightParenthesis(mklist(")")); +const value leftParenthesis(mklist("(")); +const value comment(mklist(";")); + +const double stringToNumber(const string& str) { + return atof(c_str(str)); +} + +const bool isWhitespace(const char ch) { + return ch != -1 && isspace(ch); +} + +const bool isIdentifierStart(const char ch) { + return ch != -1 && !isspace(ch) && !isdigit(ch); +} + +const bool isIdentifierPart(const char ch) { + return ch != -1 && !isspace(ch) && ch != '(' && ch != ')'; +} + +const bool isDigit(const char ch) { + return isdigit(ch) || ch == '.'; +} + +const bool isLeftParenthesis(const value& token) { + return leftParenthesis == token; +} + +const bool isRightParenthesis(const value& token) { + return rightParenthesis == token; +} + +const char readChar(istream& in) { + if(in.eof()) { + return -1; + } + char c = (char)get(in); + return c; +} + +const char peekChar(istream& in) { + if(eof(in)) + return -1; + char c = (char)peek(in); + return c; +} + +const bool isQuote(const value& token) { + return token == quoteSymbol; +} + +const failable skipComment(istream& in); +const value readQuoted(istream& in); +const value readIdentifier(const char chr, istream& in); +const value readString(istream& in); +const value readNumber(const char chr, istream& in); +const value readValue(istream& in); + +const failable readToken(istream& in) { + const char firstChar = readChar(in); + if(isWhitespace(firstChar)) + return readToken(in); + if(firstChar == ';') + return skipComment(in); + if(firstChar == '\'') + return readQuoted(in); + if(firstChar == '(') + return leftParenthesis; + if(firstChar == ')') + return rightParenthesis; + if(firstChar == '"') + return readString(in); + if(isIdentifierStart(firstChar)) + return readIdentifier(firstChar, in); + if(isDigit(firstChar)) + return readNumber(firstChar, in); + if(firstChar == -1) + return mkfailure(); + logStream() << "Illegal lexical syntax '" << firstChar << "'" << endl; + return readToken(in); +} + +const failable skipComment(istream& in) { + const char nextChar = readChar(in); + if (nextChar == '\n') + return readToken(in); + return skipComment(in); +} + +const value readQuoted(istream& in) { + return mklist(quoteSymbol, readValue(in)); +} + +const list readList(const list& listSoFar, istream& in) { + const failable ftoken = readToken(in); + if (!hasContent(ftoken)) + return reverse(listSoFar); + const value token = content(ftoken); + if(isRightParenthesis(token)) + return reverse(listSoFar); + if(isLeftParenthesis(token)) + return readList(cons(value(readList(list (), in)), listSoFar), in); + return readList(cons(token, listSoFar), in); +} + +const string listToString(const list& l) { + if(isNil(l)) + return ""; + const char buf[1] = { car(l) }; + return string(buf, 1) + listToString(cdr(l)); +} + +const list readIdentifierHelper(const list& listSoFar, istream& in) { + const char nextChar = peekChar(in); + if(isIdentifierPart(nextChar)) + return readIdentifierHelper(cons(readChar(in), listSoFar), in); + return reverse(listSoFar); +} + +const value readIdentifier(const char chr, istream& in) { + const value val = c_str(listToString(readIdentifierHelper(mklist(chr), in))); + if (val == "false") + return value((bool)false); + if (val == "true") + return value((bool)true); + if (val == "nil") + return value(); + return val; +} + +const list readStringHelper(const list& listSoFar, istream& in) { + const char nextChar = readChar(in); + if(nextChar == -1 || nextChar == '"') + return reverse(listSoFar); + if (nextChar == '\\') { + const char escapedChar = readChar(in); + if (escapedChar == -1) + return reverse(listSoFar); + return readStringHelper(cons(escapedChar, listSoFar), in); + } + return readStringHelper(cons(nextChar, listSoFar), in); +} + +const value readString(istream& in) { + return listToString(readStringHelper(list(), in)); +} + +const list readNumberHelper(const list& listSoFar, istream& in) { + const char nextChar = peekChar(in); + if(isDigit(nextChar)) + return readNumberHelper(cons(readChar(in), listSoFar), in); + return reverse(listSoFar); +} + +const value readNumber(const char chr, istream& in) { + return stringToNumber(listToString(readNumberHelper(mklist(chr), in))); +} + +const value readValue(istream& in) { + const failable fnextToken = readToken(in); + if (!hasContent(fnextToken)) + return value(); + const value nextToken = content(fnextToken); + if(isLeftParenthesis(nextToken)) + return readList(list(), in); + return nextToken; +} + +const value readValue(const string s) { + istringstream in(s); + const failable fnextToken = readToken(in); + if (!hasContent(fnextToken)) + return value(); + const value nextToken = content(fnextToken); + if(isLeftParenthesis(nextToken)) + return readList(list(), in); + return nextToken; +} + +const bool writeValue(const value& val, ostream& out) { + out << val; + return true; +} + +const string writeValue(const value& val) { + ostringstream out; + out << val; + return str(out); +} + +const value readScript(istream& in) { + const value val = readValue(in); + if (isNil(val)) + return list(); + return cons(val, (list)readScript(in)); +} + +} +} +#endif /* tuscany_scheme_io_hpp */ -- cgit v1.2.3