Skip to content
Open
Show file tree
Hide file tree
Changes from all 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 @@ -8,7 +8,7 @@
Interpreted, untyped, object-oriented and super cool.

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

## Table of Contents
Expand Down Expand Up @@ -56,12 +56,12 @@ make
<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 @@ -98,11 +98,11 @@ Any of the c-style operators can be used interchangeably with the hebrew keyword

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

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

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

// 0, 1, 2, ...
</pre>
Expand Down Expand Up @@ -142,12 +142,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 @@ -172,10 +172,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 @@ -191,14 +191,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 @@ -226,7 +226,7 @@ Similarly to Python, rpp classes can implement "magic" methods that run in certa
סניף_מרכזי = סניף('תל אביב')
סניף_מרכזי.הוסף_עובד('דניאל')

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

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

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

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

Expand All @@ -331,15 +331,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 @@ -349,10 +349,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 @@ -368,7 +368,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 @@ -388,9 +388,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 @@ -429,5 +429,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