Example #1
0
bool Parser::forward_if_next_is(char c) {
  bool result = next_is(c);

  if (result) forward();

  return result;
}
Example #2
0
ParsingResult<ast::Type *> Parser::type() {
  ParsingResult<ast::Type *> result;

  ast::Type *result_type = nullptr;

  StringParsingResult next_identifier = identifier();
  if (next_identifier.ok) {
    if (next_identifier.result == "String") {
      result_type = new ast::StringType;
    }

    if (next_identifier.result == "i32") {
      result_type = new ast::I32Type;
    }
  }

  if (result_type) {
    while (next_is('[')) {
      forward();

      // parse digit...
      if (forward_if_next_is(']')) {
        ast::ArrayType *array = new ast::ArrayType;
        array->of.reset(result_type);
        array->dynamic = true;

        result_type = array;
      }
    }
  }

  if (result_type) {
    result.ok = true;
    result.result = result_type;
  }

  return result;
}
Example #3
0
std::shared_ptr<Token> Lexer::scan()
{
    skip_whitespace();

    switch (peek) {
        case '=':
            if (next_is('=')) {
                return std::make_shared<Word>(Tag::EQUALS, "==");
            } else {
                return std::make_shared<Token>('=');
            }

            break;
        default:
            break;
    }

    // Numbers: [0-9]+(\.[0-9]+f?)?
    if (isdigit(peek)) {
        std::stringstream buffer;
        buffer << peek;

        while (next() && isdigit(peek)) {
            buffer << peek;
        }

        if (peek == '.') {
            buffer << peek;

            while (next() && isdigit(peek)) {
                buffer << peek;
            }

            if (peek == 'f') {
                return std::make_shared<Word>(Tag::FLOAT, buffer.str());
            } else {
                return std::make_shared<Word>(Tag::DOUBLE, buffer.str());
            }
        } else {
            if (isalpha(peek)) {
                if (peek == 'f') {
                    if (next() && isalpha(peek)) {
                        throw "Invalid number at line";
                    }

                    return std::make_shared<Word>(Tag::FLOAT, buffer.str());
                } else {
                    throw "Invalid number";
                }
            }

            return std::make_shared<Word>(Tag::INTEGER, buffer.str());
        }
    }

    // Identifiers [a-zA-Z][a-zA-Z0-9]+
    if (isalpha(peek)) {
        std::stringstream buffer;
        buffer << peek;

        while (next() && isalnum(peek)) {
            buffer << peek;
        }

        std::string lexeme = buffer.str();

        auto iterator = words.find(lexeme);
        if (iterator != words.end()) {
            return iterator->second;

        } else {
            auto token = std::make_shared<Word>(Tag::IDENTIFIER, lexeme);
            reserve(token);

            return token;
        }
    }

    // Strings.
    auto string = match_string();

    if (string != nullptr) {
        return string;
    }

    auto token = std::make_shared<Token>(peek);

    clean_peek();
    return token;
}
Example #4
0
ParsingResult<ast::Signature *> Parser::signature() {
  ParsingResult<ast::Signature *> result;

  StringParsingResult next_identifier = identifier();
  if (!next_identifier.ok) return result;

  skip();

  ast::Type *return_type;
  if (forward_if_next_is('#')) {
    ParsingResult<ast::Type *> preturn_type = type();
    if (!preturn_type) return fail<ast::Signature *>();

    return_type = preturn_type.result;
  } else {
    return_type = new ast::VoidType();
  }

  skip();

  std::vector<std::tuple<std::string, std::string, ast::Type *>> list;

  bool fallback = false;

  do {
    if (fallback) {
      // We do a loop without consume anything, try to consume one
      forward();
    }

    fallback = true;

    std::string ralias;
    std::string ridentifier;

    StringParsingResult palias = alias();

    if (palias) {
      skip();

      ralias = palias.result;
    }

    StringParsingResult pidentifier = identifier();

    if (pidentifier) {
      skip();

      ridentifier = pidentifier.result;

      if (forward_if_next_is('#')) {
        ParsingResult<ast::Type *> ptype = type();
        if (!ptype) throw "An argument in not typed";

        list.push_back(std::make_tuple(ralias, ridentifier, ptype.result));

        fallback = false;
      }
    }

    skip();
  } while (!next_is('{'));

  ast::Signature *signature = new ast::Signature;
  signature->identifier = next_identifier.result;
  signature->ret.reset(return_type);

  for (const std::tuple<std::string, std::string, ast::Type *> &l : list) {
    signature->params.emplace_back();

    signature->params.back().type.reset(std::get<2>(l));
    signature->params.back().alias = std::get<0>(l);
    signature->params.back().identifier = std::get<1>(l);
  }

  result.ok = true;
  result.result = signature;

  return result;
}