Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,4 @@
.idea
cmake-build-debug/
.vscode/
benchmark_log.txt
82 changes: 41 additions & 41 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
Interpreted, untyped, object-oriented and super cool.

<pre dir="rtl" align="right">
פלוט 'שלום עולם!'
הדפס 'שלום עולם!'
</pre>

## Table of Contents
Expand Down Expand Up @@ -66,12 +66,12 @@ g++ -std=c++17 -O3 src/*.h src/*.cpp -o rpp
<pre dir="rtl" align="right">
מ = 10
מ = מ / 100
פלוט מ // 0.1
הדפס מ // 0.1
מ = ((מ ** 2) * 300) % 40
פלוט מ // 3
פלוט מ שווהל 100 או 1 == 1 // true
פלוט מ גדולמ 70 וגם שקר // false
פלוט לא (מ קטןמ 0.34) // true
הדפס מ // 3
הדפס מ שווהל 100 או 1 == 1 // true
הדפס מ גדולמ 70 וגם שקר // false
הדפס לא (מ קטןמ 0.34) // true
</pre>

<a name="vars-operators"/>
Expand Down Expand Up @@ -108,11 +108,11 @@ Any of the c-style operators can be used interchangeably with the hebrew keyword

כלעוד מ קטןמ 10:
אם מ שווהל 2:
פלוט 'שתיים'
הדפס 'שתיים'
אחרת אם מ % 2 == 0:
פלוט 'זוגי'
הדפס 'זוגי'
אחרת:
פלוט 'אי-זוגי'
הדפס 'אי-זוגי'
מ = מ + 1

// אי-זוגי
Expand All @@ -122,7 +122,7 @@ Any of the c-style operators can be used interchangeably with the hebrew keyword
// ...

לכל מ בתוך טווח(100):
פלוט מ
הדפס מ

// 0, 1, 2, ...
</pre>
Expand Down Expand Up @@ -152,12 +152,12 @@ All code blocks can be written in a one-line form or a multi-line indented block

<pre dir="rtl" align="right">
כלעוד אמת:
פלוט 1
הדפס 1

כלעוד אמת פלוט 1
כלעוד אמת הדפס 1

אם שקר פלוט 1 אחרת אם אמת פלוט 2 אחרת:
פלוט 3
אם שקר הדפס 1 אחרת אם אמת הדפס 2 אחרת:
הדפס 3
// 2
</pre>

Expand All @@ -182,10 +182,10 @@ Functions in rpp are declared similarly to JavaScript - they can be declared by
החזר 1
החזר פיב(מ - 1) + פיב(מ - 2)

פלוט_פיב = פעולה(מ) פלוט פיב(מ)
הדפס_פיב = פעולה(מ) הדפס פיב(מ)

לכל מ בתוך טווח(5):
פלוט_פיב(מ)
הדפס_פיב(מ)

// 1, 1, 2, 3, 5, ...
</pre>
Expand All @@ -201,14 +201,14 @@ Class declarations are declared similarly to functions (named or anonymous)
פעולה כפל(א, ב):
החזר א * ב

פלוט חישובים.כפל(4, 2)
הדפס חישובים.כפל(4, 2)
// 8

חישובים2 = מחלקה:
פעולה ריבוע(מ):
החזר מ ** 2

פלוט חישובים2.ריבוע(3)
הדפס חישובים2.ריבוע(3)
// 9
</pre>

Expand Down Expand Up @@ -236,7 +236,7 @@ Similarly to Python, rpp classes can implement "magic" methods that run in certa
סניף_מרכזי = סניף('תל אביב')
סניף_מרכזי.הוסף_עובד('דניאל')

פלוט סניף_מרכזי
הדפס סניף_מרכזי

// תל אביב: [דניאל]
</pre>
Expand Down Expand Up @@ -268,7 +268,7 @@ Exceptions are thrown and caught by class type
ר = רשימה(1, 2)
ר[23]
תפוס __שגיאת_מיקום__:
פלוט 'שיט'
הדפס 'שיט'

פעולה זורק():
ערך = רשימה(1, 2)
Expand All @@ -277,7 +277,7 @@ Exceptions are thrown and caught by class type
נסה:
זורק()
תפוס רשימה בתור א:
פלוט א
הדפס א
</pre>

<a name="exceptions-types"/>
Expand All @@ -301,14 +301,14 @@ As all great programming languages, rpp is equipped with some useful built-ins
<pre dir="rtl" align="right">
ר = רשימה(1,2,3)
ר[2] = אמת
פלוט ר.גודל() // 3
הדפס ר.גודל() // 3
ר.הוסף('שלום')
ר.הוצא(0)
פלוט ר.מצא(אמת) // 2
פלוט ר.מצא('היי') // -1
פלוט ר // [אמת, 3, 'שלום']
הדפס ר.מצא(אמת) // 2
הדפס ר.מצא('היי') // -1
הדפס ר // [אמת, 3, 'שלום']
לכל איבר בתוך ר:
פלוט איבר
הדפס איבר
</pre>

<a name="built-ins-dict"/>
Expand All @@ -323,12 +323,12 @@ For looping a Dictionary will yield it's keys
ר = מילון()
ר['שם'] = 'רשי ועוד ועוד'
ר['גרסה'] = '0.1'
פלוט ר.גודל() // 2
הדפס ר.גודל() // 2
ר.הוצא('גרסה')
פלוט ר.מכיל('שם') // אמת
פלוט ר // {'שם': 'רשי ועוד ועוד'}
הדפס ר.מכיל('שם') // אמת
הדפס ר // {'שם': 'רשי ועוד ועוד'}
לכל מפתח בתוך ר:
פלוט מפתח
הדפס מפתח
// שם
</pre>

Expand All @@ -341,15 +341,15 @@ Similarly to Python, rpp has a built-in Range functionality, with two calling si
- Iterate from min to max-1: `טווח(10, 20)`

<pre dir="rtl" align="right">
לכל מ בתוך טווח(10) אם מ % 2 שווהל 0 פלוט "זוגי" אחרת פלוט "איזוגי"
לכל מ בתוך טווח(10) אם מ % 2 שווהל 0 הדפס "זוגי" אחרת הדפס "איזוגי"
// זוגי, איזוגי, ...
</pre>

<a name="built-ins-io"/>

### I/O

- Printing to console: the `פלוט` command.
- Printing to console: the `הדפס` command.
- Receiving input from the user: the `(פלט)קלוט` function

Currently, Rashi Plus Plus supports hebrew I/O in the console!
Expand All @@ -359,10 +359,10 @@ Currently, Rashi Plus Plus supports hebrew I/O in the console!
(To enable hebrew in the windows console, please enable a TrueType font such as "Courier New")

<pre dir="rtl" align="right">
פלוט 'שלום'
פלוט 90
פלוט אמת
פלוט רשימה()
הדפס 'שלום'
הדפס 90
הדפס אמת
הדפס רשימה()

קלוט('>')
קלוט('מי אתה? ')
Expand All @@ -378,7 +378,7 @@ Similarly to Python, rpp has a built-in Range functionality, with two calling si
2. Iterate [min, max): `טווח(10, 20)`

<pre dir="rtl" align="right">
לכל מ בתוך טווח(10) אם מ % 2 שווהל 0 פלוט "זוגי" אחרת פלוט "איזוגי"
לכל מ בתוך טווח(10) אם מ % 2 שווהל 0 הדפס "זוגי" אחרת הדפס "איזוגי"
// זוגי, איזוגי, ...
</pre>

Expand All @@ -398,9 +398,9 @@ Three random function signatures:
- String literals can be written with single (') or double (") quotes

<pre dir="rtl" align="right">
פלוט "המספר הוא " + טקסט(34) // המספר הוא 34
פלוט מספר("3") * 2 // 6
פלוט סוג(אמת) // <bool>
הדפס "המספר הוא " + טקסט(34) // המספר הוא 34
הדפס מספר("3") * 2 // 6
הדפס סוג(אמת) // <bool>
</pre>

<a name="patterns"/>
Expand Down Expand Up @@ -439,5 +439,5 @@ To implement an Iterator in rpp, a class must implement the following:
שמות = קומבינציות(רשימה('דניאל', 'דני', 'רון'), רשימה('שמעון', 'בכר'))

לכל שם בתוך שמות:
פלוט שם
הדפס שם
</pre>
12 changes: 6 additions & 6 deletions examples/inventory.rpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@
מוצר = קלוט_מוצר()
מיקום = מחסן.מצא(מוצר)
אם מיקום >= 0 מחסן.הוצא(מיקום) אחרת:
פלוט מוצר + ' לא נמצא'
הדפס מוצר + ' לא נמצא'
אחרת אם פקודה שווהל 'הראה':
פלוט 'מחסן:'
הדפס 'מחסן:'
לכל מוצר בתוך מחסן:
פלוט מוצר
פלוט טקסט(מחסן.גודל()) + ' פריטים סה"כ'
הדפס מוצר
הדפס טקסט(מחסן.גודל()) + ' פריטים סה"כ'
אחרת:
פלוט 'פקודה לא מוכרת: ' + פקודה
פלוט 'שימוש: הוסף, הוצא, הראה, צא'
הדפס 'פקודה לא מוכרת: ' + פקודה
הדפס 'שימוש: הוסף, הוצא, הראה, צא'
6 changes: 3 additions & 3 deletions examples/primes.rpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
ראשוניים = רשימה()
פלוט 'שלום'
הדפס 'שלום'
יעד = מספר(קלוט('בחר ערך מקסימלי: '))

לכל נוכחי בתוך טווח(יעד - 2):
Expand All @@ -11,5 +11,5 @@
שבור
אם סבבה ראשוניים.הוסף(נוכחי)

פלוט 'והראשוניים הם:'
פלוט ראשוניים
הדפס 'והראשוניים הם:'
הדפס ראשוניים
8 changes: 4 additions & 4 deletions src/Hebrew.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@

#include "Hebrew.h"

string Hebrew::englishify(string value) {
string output = "";
string Hebrew::englishify(const string& value) {
string output;

string::iterator it = value.begin();
auto it = value.begin();
while (it != value.end()) {
string::iterator prev = it;
auto prev = it;
uint32_t ch = utf8::next(it, value.end());
if (charMap.count(ch) == 0)
output += string(prev, it);
Expand Down
2 changes: 1 addition & 1 deletion src/Hebrew.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ namespace Hebrew {
map<uint32_t, string> charMap = createCharMap();
}

string englishify(string value);
string englishify(const string& value);
void print(const string& value, bool endLine=true, bool rtl=true);
void print(const char* value, bool endLine=true, bool rtl=true);
string read(bool rtl=true);
Expand Down
7 changes: 5 additions & 2 deletions src/Interpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -234,11 +234,14 @@ bool Interpreter::equalityEvaluation(Value *first, Value *second) {

// region execution

Value *Interpreter::execute(vector<Statement *> statements, bool evaluate) {

template Value* Interpreter::execute<true>(vector<Statement*> statements);
template Value* Interpreter::execute<false>(vector<Statement*> statements);
template<bool evaluate> Value *Interpreter::execute(vector<Statement *> statements) {
Value *returnValue = Value::None;
for (Statement *statement : statements) {
try {
if (evaluate)
if constexpr (evaluate)
if (ExpressionStatement *expression = dynamic_cast<ExpressionStatement *>(statement)) {
returnValue = executeExpression(expression);
break;
Expand Down
2 changes: 1 addition & 1 deletion src/Interpreter.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ class Interpreter : public ExpressionVisitor, public StatementVisitor {
Value* evaluateClass(ClassExpression* call);
Value* evaluateGet(GetExpression* call);

Value* execute(vector<Statement*> statements, bool evaluate = false);
template<bool evaluate> Value* execute(vector<Statement*> statements);
Value* executeExpression(ExpressionStatement* statement);
void executeCommand(CommandStatement *statement);
void executeIf(IfStatement* statement);
Expand Down
31 changes: 22 additions & 9 deletions src/Lexer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,22 @@
//
#include "Lexer.h"

Lexer::Lexer(string* source)
Lexer::Lexer(string&& source)
{
start = source->begin();
iterator = start;
end = source->end();
this->source = source;
iterator = this->source.begin();
end = this->source.end();
}

vector<Token*> Lexer::scan() {
vector<shared_ptr<Token>> Lexer::scan() {
try {
return _scan();
} catch (utf8::exception& e) {
invalidUTF8(Token::errorSignature(line, index - 1))
}
}

inline vector<Token*> Lexer::_scan() {
inline vector<shared_ptr<Token>> Lexer::_scan() {
while (iterator < end)
{
uint32_t ch = next();
Expand Down Expand Up @@ -111,7 +111,7 @@ inline vector<Token*> Lexer::_scan() {
}

void Lexer::addToken(TokenType type, string lexeme, void* value) {
tokens.emplace_back(new Token(type, lexeme, value, line, index));
tokens.push_back(make_shared<Token>(type, lexeme, value, line, index));
}

bool Lexer::isAtEnd() {
Expand Down Expand Up @@ -165,7 +165,7 @@ void Lexer::scanString(char delimiter) {

void Lexer::scanNumber() {
string::iterator start = iterator;
utf8::prior(start, this->start);
utf8::prior(start, this->source.begin());

while (isDigit(peek()))
next();
Expand All @@ -183,7 +183,7 @@ void Lexer::scanNumber() {

void Lexer::scanIdentifier() {
string::iterator start = iterator;
utf8::prior(start, this->start);
utf8::prior(start, this->source.begin());

while (isAlpha(peek()) || isDigit(peek()) || peek() == '_')
next();
Expand All @@ -196,6 +196,19 @@ void Lexer::scanIdentifier() {
addToken(Identifier, value, new string(value));
}

Token::~Token() {
switch (this->type) {
case NumberLiteral:
delete (double*)this->value;
break;
case StringLiteral:
case Identifier:
delete (string*)this->value;
default:
return;
}
}

string Token::errorSignature() {
return Token::errorSignature(line, index, lexeme);
}
Expand Down
Loading