Skip to content

Commit

Permalink
let done
Browse files Browse the repository at this point in the history
  • Loading branch information
amanuel2 committed Jun 25, 2024
1 parent ee3d82d commit 240c91a
Show file tree
Hide file tree
Showing 10 changed files with 95 additions and 17 deletions.
10 changes: 9 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

# sets targets
include(Options.mk)
include(FindReadline.mk)

# "#includes"
include_directories(${CMAKE_SOURCE_DIR}/include)
Expand All @@ -49,4 +50,11 @@ include_directories(${gmock_SOURCE_DIR}/include ${gmock_SOURCE_DIR})
# add_subdirectory(external/abseil)
# find_package(absl REQUIRED)
# include_directories(${abseil_SOURCE_DIR})
# target_link_libraries(riftlang absl::base absl::synchronization absl::strings)
# target_link_libraries(riftlang absl::base absl::synchronization absl::strings)

#readline library for interpreter
# find_package(Readline REQUIRED)
# if READLINE_FOUND is false then fail
if(NOT READLINE_FOUND)
message(FATAL_ERROR "Readline not found")
endif()
49 changes: 49 additions & 0 deletions FindReadline.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Code copied from sethhall@github
#
# - Try to find readline include dirs and libraries
#
# Usage of this module as follows:
#
# find_package(Readline)
#
# Variables used by this module, they can change the default behaviour and need
# to be set before calling find_package:
#
# Readline_ROOT_DIR Set this variable to the root installation of
# readline if the module has problems finding the
# proper installation path.
#
# Variables defined by this module:
#
# READLINE_FOUND System has readline, include and lib dirs found
# Readline_INCLUDE_DIR The readline include directories.
# Readline_LIBRARY The readline library.

find_path(Readline_ROOT_DIR
NAMES include/readline/readline.h
)

find_path(Readline_INCLUDE_DIR
NAMES readline/readline.h
HINTS ${Readline_ROOT_DIR}/include
)

find_library(Readline_LIBRARY
NAMES readline
HINTS ${Readline_ROOT_DIR}/lib
)

if(Readline_INCLUDE_DIR AND Readline_LIBRARY AND Ncurses_LIBRARY)
set(READLINE_FOUND TRUE)
else(Readline_INCLUDE_DIR AND Readline_LIBRARY AND Ncurses_LIBRARY)
FIND_LIBRARY(Readline_LIBRARY NAMES readline)
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Readline DEFAULT_MSG Readline_INCLUDE_DIR Readline_LIBRARY )
MARK_AS_ADVANCED(Readline_INCLUDE_DIR Readline_LIBRARY)
endif(Readline_INCLUDE_DIR AND Readline_LIBRARY AND Ncurses_LIBRARY)

mark_as_advanced(
Readline_ROOT_DIR
Readline_INCLUDE_DIR
Readline_LIBRARY
)
1 change: 1 addition & 0 deletions include/ast/env.hh
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ namespace rift
}
Token getEnv(const str_t& name) const;
void setEnv(const str_t& name, const Token& value);
void printState();
protected:
// absl::flat_hash_map<str_t, rift::scanner::Token> values;
std::unordered_map<str_t, rift::scanner::Token> values = {};
Expand Down
4 changes: 3 additions & 1 deletion include/reader/reader.hh
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,9 @@ namespace rift
// inline typename std::enable_if<!std::is_same<T, char>::value, T>::type advance() { return (!atEnd()) ? source->at(curr++) : nullptr; }

/// @brief Peeks at the current character
inline bool peek(T expected) { return !atEnd() && source->at(curr) == expected; };
inline bool peek(T expected) {
return !atEnd() && source->at(curr) == expected;
};
/// @brief Peeks at the current character with an offset
inline bool peek_off(T expected, int offset) { return curr+offset<source->size() && source->at(curr+offset) == expected; };
/// @brief Peeks at the current character
Expand Down
3 changes: 2 additions & 1 deletion include/scanner/scanner.hh
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@ namespace rift

inline bool isDigit(char c) { return c>='0' && c<='9'; }
inline bool isAlpha(char c) { return (c!=' ') && ( (c>='a' && c<='z') || (c>='A' && c<='Z') || c=='_'); }
inline bool isAlphaNumeric(char c) { return isAlpha(c) || isDigit(c); }
inline bool isAlphaNumeric(char c) { return std::isalnum(c); }
inline bool isIdentifier(char c) { return std::isalnum(c) || c == '_'; }

#pragma mark - Token Scanners

Expand Down
1 change: 1 addition & 0 deletions lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ add_executable(
target_compile_options(riftlang PRIVATE -Wno-gcc-compat)
target_compile_definitions(riftlang PRIVATE ABSL_USES_STD_ANY=1)

target_link_libraries(riftlang PRIVATE Readline)
# target_link_libraries(riftlang absl::base absl::strings absl::hash absl::algorithm absl::memory absl::flat_hash_map absl::container_common absl::container_memory)

add_library(riftlib STATIC ${SOURCES})
Expand Down
10 changes: 7 additions & 3 deletions lib/ast/env.cc
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,6 @@ namespace rift
// if(tok == Token())
// rift::error::runTimeError("🛑 Undefined variable '" + name + "'");
// }
for (const auto& [key, value] : values) {
std::cout << key << " => " << value.to_string() << std::endl;
}
if (!values.contains(name)) {
return Token();
}
Expand All @@ -37,5 +34,12 @@ namespace rift
{
values[name] = value;
}

void Environment::printState()
{
for (const auto& [key, value] : values) {
std::cout << key << " => " << value.to_string() << std::endl;
}
}
}
}
9 changes: 7 additions & 2 deletions lib/ast/parser.cc
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,11 @@ namespace rift
if (match({Token(TokenType::IDENTIFIER, "", "", line)})) {
/// @note rhs identifier undeclared
auto idt = peekPrev(1);
if (rift::ast::Environment::getInstance().getEnv(castString(idt)) == Token()) {
auto val = rift::ast::Environment::getInstance().getEnv(castString(idt));
if (val == Token()) {
rift::error::report(line, "primary", "🛑 Undefined variable '" + castString(idt) + "' at line: " + castNumberString(idt.line), idt, ParserException("Undefined variable '" + castString(idt) + "'"));
}
return std::unique_ptr<Literal>(new Literal(Token(peekPrev(1))));
return std::unique_ptr<Literal>(new Literal(Token(val)));
}

if (match({Token(TokenType::LEFT_PAREN, "(", "", line)})) {
Expand Down Expand Up @@ -154,6 +155,10 @@ namespace rift
std::unique_ptr<Expr> Parser::assignment()
{
if (match({Token(TokenType::IDENTIFIER, "", "", line)})) {
if (peek(Token(TokenType::SEMICOLON, ";", "", line))) {
prevance();
return equality();
}
auto idt = peekPrev();
consume(Token(TokenType::EQUAL, "=", "", line), std::unique_ptr<ParserException>(new ParserException("Expected '=' after variable name")));
auto expr = assignment();
Expand Down
21 changes: 14 additions & 7 deletions lib/driver/driver.cc
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@
#include <ast/eval.hh>
#include <string>

#include <readline/readline.h>
#include <readline/history.h>

using namespace rift::error;
using namespace rift::scanner;
using namespace rift::ast;
Expand All @@ -51,6 +54,7 @@ namespace rift

Eval riftEvaluator;
riftEvaluator.evaluate(*statements);
rift::ast::Environment::getInstance().printState();
}

void Driver::runFile()
Expand Down Expand Up @@ -85,14 +89,17 @@ namespace rift

void Driver::runPrompt()
{
while(true)
{
std::string input = "";
std::cout << "🦊 > ";
std::getline(std::cin >> std::ws, input);
if (input.empty()) break;
rl_bind_key('\t', rl_complete);
while(true) {
char* input = readline("🦊 > ");
if (input == nullptr) break;
add_history(input);

run(input);
errorOccured = false; // reset error

// reset
errorOccured = false;
free(input);
}
}

Expand Down
4 changes: 2 additions & 2 deletions lib/scanner/scanner.cc
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ namespace rift
keywords["super"] = Type::SUPER;
keywords["this"] = Type::THIS;
keywords["true"] = Type::TRUE;
keywords["var"] = Type::VAR;
keywords["let"] = Type::VAR;
keywords["while"] = Type::WHILE;
}

Expand Down Expand Up @@ -94,7 +94,7 @@ namespace rift
}

void Scanner::identifier() {
while (isAlphaNumeric(advance()));
while (isIdentifier(peek())) advance();
std::string text = std::string(source->begin()+start, source->begin()+curr);
text.erase(std::remove_if(text.begin(), text.end(), ::isspace), text.end());
if (keywords.find(text)!= keywords.end()) {
Expand Down

0 comments on commit 240c91a

Please sign in to comment.