Skip to content

Commit 5a5864c

Browse files
Implemented basic OOP.
Implemented basic OOP. Tests have not been added yet.
1 parent e6d109c commit 5a5864c

36 files changed

+1112
-575
lines changed

Cargo.lock

+26
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+3
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@ edition = "2021"
99
anyhow = { version = "1.0.71", features = ["backtrace"] }
1010
backtrace = "0.3.68"
1111
const-str = "0.5.6"
12+
debug-ignore = "1.0.5"
1213
delegate = "0.10.0"
14+
derivative = "2.2.0"
15+
either = "1.9.0"
1316
extend = "1.2.0"
1417
gc = { version = "0.5.0", features = ["derive", "gc_derive"] }
1518
lazy_static = "1.4.0"

src/lib/ast/expression.rs

+15-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::ast::operator::Operator;
22
use crate::ast::statement::Statement;
3-
use crate::ast::structs::{CallExpression, FunctionDeclaration};
3+
use crate::ast::structs::{CallExpression, ClassDeclaration, FunctionDeclaration};
44

55
pub type BoxExpression = Box<Expression>;
66

@@ -10,6 +10,7 @@ pub type IdentifierT = String;
1010
pub enum MemberIndexer {
1111
PropertyName(IdentifierT),
1212
SubscriptExpression(BoxExpression),
13+
MethodNameArrow(IdentifierT),
1314
}
1415

1516
#[derive(Debug, Clone, Eq, PartialEq)]
@@ -18,8 +19,9 @@ pub enum Expression {
1819
BooleanLiteral(bool),
1920
IntegerLiteral(i64),
2021
StringLiteral(String),
22+
ParenthesizedExpression(BoxExpression),
2123
// ThisExpression,
22-
SuperExpression,
24+
// SuperExpression,
2325
UnaryExpression {
2426
operator: Operator,
2527
argument: BoxExpression,
@@ -42,6 +44,7 @@ pub enum Expression {
4244
FunctionCall(CallExpression),
4345
NewObjectExpression(CallExpression),
4446
FunctionExpression(FunctionDeclaration),
47+
ClassDeclarationExpression(Box<ClassDeclaration>),
4548
}
4649

4750
impl Expression {
@@ -60,6 +63,11 @@ impl Expression {
6063
return Expression::AssignmentExpression { operator, left, right };
6164
}
6265

66+
#[inline(always)]
67+
pub fn member_method_access(object: BoxExpression, property_name: IdentifierT) -> Expression {
68+
return Expression::MemberAccess { object, member: MemberIndexer::MethodNameArrow(property_name) };
69+
}
70+
6371
#[inline(always)]
6472
pub fn member_property_access(object: BoxExpression, property_name: IdentifierT) -> Expression {
6573
return Expression::MemberAccess { object, member: MemberIndexer::PropertyName(property_name) };
@@ -93,4 +101,9 @@ impl Expression {
93101
pub fn consume_as_statement(self) -> Statement {
94102
return Statement::from(self);
95103
}
104+
105+
#[inline(always)]
106+
pub fn consume_as_parenthesized(self) -> Expression {
107+
return Expression::ParenthesizedExpression(self.into());
108+
}
96109
}

src/lib/ast/statement.rs

+3-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::ast::expression::{Expression, IdentifierT};
2-
use crate::ast::structs::{FunctionDeclaration, FunctionParameterDeclaration, VariableDeclaration};
2+
use crate::ast::structs::{ClassDeclaration, FunctionDeclaration, FunctionParameterDeclaration, VariableDeclaration};
33

44
pub type BoxStatement = Box<Statement>;
55

@@ -34,11 +34,7 @@ pub enum Statement {
3434
BreakStatement(i64),
3535
ContinueStatement(i64),
3636
FunctionDeclarationStatement(FunctionDeclaration),
37-
ClassDeclarationStatement {
38-
name: IdentifierT,
39-
super_class: Option<Expression>,
40-
methods: Vec<FunctionDeclaration>,
41-
},
37+
ClassDeclarationStatement(ClassDeclaration),
4238
}
4339

4440
impl Statement {
@@ -91,7 +87,7 @@ impl Statement {
9187
super_class: Option<Expression>,
9288
methods: Vec<FunctionDeclaration>,
9389
) -> Statement {
94-
return Statement::ClassDeclarationStatement { name, super_class, methods };
90+
return Statement::ClassDeclarationStatement(ClassDeclaration::new(name, super_class, methods));
9591
}
9692
}
9793

src/lib/ast/structs.rs

+14
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,20 @@ impl FunctionDeclaration {
4040
}
4141
}
4242

43+
#[derive(Debug, Clone, Eq, PartialEq)]
44+
pub struct ClassDeclaration {
45+
pub name: IdentifierT,
46+
pub super_class: Option<Expression>,
47+
pub methods: Vec<FunctionDeclaration>,
48+
}
49+
50+
impl ClassDeclaration {
51+
#[inline(always)]
52+
pub fn new(name: IdentifierT, super_class: Option<Expression>, methods: Vec<FunctionDeclaration>) -> Self {
53+
Self { name, super_class, methods }
54+
}
55+
}
56+
4357
#[derive(Debug, Clone, Eq, PartialEq)]
4458
pub struct CallExpression {
4559
pub callee: BoxExpression,

src/lib/errors.rs

+63-4
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,66 @@ use crate::ast::expression::{Expression, IdentifierT};
88
use crate::ast::operator::Operator;
99
use crate::ast::statement::Statement;
1010
use crate::interpreter::environment::statement_result::StatementExecution;
11+
use crate::interpreter::runtime_values::PrimitiveValue;
1112
use crate::tokenizer::Token;
1213

1314
pub type ResultWithError<T, E = EvilangError> = anyhow::Result<T, E>;
1415

16+
#[derive(Debug, Clone, PartialEq)]
17+
pub enum Descriptor {
18+
None,
19+
Name(IdentifierT),
20+
Value(PrimitiveValue),
21+
Expression(Expression),
22+
Both { value: PrimitiveValue, expression: Expression },
23+
}
24+
25+
impl From<&str> for Descriptor {
26+
fn from(value: &str) -> Self {
27+
Descriptor::Name(value.to_string())
28+
}
29+
}
30+
31+
impl From<IdentifierT> for Descriptor {
32+
fn from(value: IdentifierT) -> Self {
33+
Descriptor::Name(value)
34+
}
35+
}
36+
37+
impl From<PrimitiveValue> for Descriptor {
38+
fn from(value: PrimitiveValue) -> Self {
39+
Descriptor::Value(value)
40+
}
41+
}
42+
43+
impl From<Expression> for Descriptor {
44+
fn from(value: Expression) -> Self {
45+
Descriptor::Expression(value)
46+
}
47+
}
48+
49+
#[derive(Debug, Clone, PartialEq, Error)]
50+
pub enum RuntimeError {
51+
#[error("{0}")]
52+
GenericError(String),
53+
#[error("Expected {0:#?} to be a function")]
54+
ExpectedFunction(Descriptor),
55+
#[error("Expected {0:#?} to be a class object")]
56+
ExpectedClassObject(Descriptor),
57+
#[error("Expected {0:#?} to be an object")]
58+
ExpectedObject(Descriptor),
59+
#[error("Invalid number of arguments {got:?} expected {expected:?} to be function {func:#?}")]
60+
InvalidNumberArgumentsToFunction { got: usize, expected: Option<String>, func: Descriptor },
61+
#[error("Expected {0:#?} to be a valid subscript expression")]
62+
ExpectedValidSubscript(Descriptor),
63+
}
64+
1565
#[derive(Debug, Clone, PartialEq, Error)]
1666
pub enum ErrorT {
17-
#[error("This error should never happen")]
18-
NeverError,
67+
#[error("This error should never happen: {0}")]
68+
NeverError(String),
69+
#[error(transparent)]
70+
UnexpectedRuntimeError(#[from] RuntimeError),
1971
#[error("End of Token Stream")]
2072
EndOfTokenStream,
2173
#[error("Invalid Token Type: {0:#?}")]
@@ -38,8 +90,6 @@ pub enum ErrorT {
3890
UnimplementedBinaryOperatorForValues(Operator, Expression, Expression),
3991
#[error("The interpreter does not support the unary operator: {0:?} for the value {1:#?}")]
4092
UnimplementedUnaryOperatorForValues(Operator, Expression),
41-
#[error("The following expression is not a function: {0:?}")]
42-
NotAFunction(Expression),
4393
#[error("A mutable borrow already exists")]
4494
InvalidBorrow,
4595
#[error("The cannot strip assignment from operator: {0:?}")]
@@ -52,6 +102,8 @@ pub enum ErrorT {
52102
CantSetToHoistedValue,
53103
#[error("Invalid unrolling from function {0:?}: {1:#?}")]
54104
InvalidUnrollingOfFunction(IdentifierT, StatementExecution),
105+
#[error("Member functions accessed by the arrow notation mus be immediately called: {0:#?}")]
106+
InvalidMethodArrowAccess(Expression),
55107
}
56108

57109
#[derive(Debug, Clone)]
@@ -85,6 +137,13 @@ impl From<ErrorT> for EvilangError {
85137
}
86138
}
87139

140+
impl From<RuntimeError> for EvilangError {
141+
#[inline(always)]
142+
fn from(value: RuntimeError) -> Self {
143+
return EvilangError::new(ErrorT::UnexpectedRuntimeError(value));
144+
}
145+
}
146+
88147
impl EvilangError {
89148
#[inline(always)]
90149
pub fn new(typ: ErrorT) -> EvilangError {

src/lib/interpreter/environment/default_global_scope.rs

+12-2
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,25 @@
11
use crate::interpreter::environment::native_functions::get_native_functions_list;
2+
use crate::interpreter::runtime_values::objects::runtime_object::RuntimeObject;
23
use crate::interpreter::runtime_values::PrimitiveValue;
3-
use crate::interpreter::variables_map::{GlobalScope, VariablesMap};
4+
use crate::interpreter::variables_containers::{GlobalScope, VariablesMap};
45
use crate::utils::cell_ref::{gc_box_from, GcBox};
6+
use crate::interpreter::utils::consts::{OBJECT};
7+
8+
pub fn get_object_class() -> GcBox<RuntimeObject> {
9+
return RuntimeObject::new_gc(VariablesMap::new(), None, OBJECT.into());
10+
}
511

612
fn get_default_global_variables() -> VariablesMap {
713
return VariablesMap::new_direct(
814
get_native_functions_list()
915
.into_iter()
1016
.map(|(name, f)| {
11-
(name, gc_box_from(PrimitiveValue::new_native_function(f)))
17+
(name, PrimitiveValue::new_native_function(f))
1218
})
19+
.chain([
20+
(OBJECT.to_string(), PrimitiveValue::Object(get_object_class()))
21+
].into_iter())
22+
.map(|(name, val)| (name, gc_box_from(val)))
1323
.collect()
1424
);
1525
}

0 commit comments

Comments
 (0)