Skip to content

Commit 4efdbaf

Browse files
Merge pull request #57 from EdwardPalmer99/EdwardPalmer99/add-benchmarking-and-casts
AnyObject
2 parents 2ede7cc + 6c56845 commit 4efdbaf

74 files changed

Lines changed: 1208 additions & 1394 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

src/environment/Scope.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
*/
99

1010
#include "Scope.hpp"
11+
#include "AnyObject.hpp"
1112
#include "Exceptions.hpp"
1213
#include <cassert>
1314

@@ -22,7 +23,7 @@ Scope::Scope(const Scope *_parent)
2223
}
2324

2425

25-
BaseObject::Ptr Scope::getOptionalNamedObject(const std::string &name) const
26+
AnyObject::Ptr Scope::getOptionalNamedObject(const std::string &name) const
2627
{
2728
// Try in our scope (to handle variable shadowing).
2829
auto iter = linkedObjectForName.find(name);
@@ -42,9 +43,9 @@ BaseObject::Ptr Scope::getOptionalNamedObject(const std::string &name) const
4243
}
4344

4445

45-
BaseObject::Ptr Scope::getNamedObject(const std::string &name) const
46+
AnyObject::Ptr Scope::getNamedObject(const std::string &name) const
4647
{
47-
BaseObject::Ptr obj = getOptionalNamedObject(name);
48+
AnyObject::Ptr obj = getOptionalNamedObject(name);
4849
if (!obj)
4950
{
5051
ThrowException("undefined variable " + name);
@@ -60,7 +61,7 @@ bool Scope::hasNamedObject(const std::string &name) const
6061
}
6162

6263

63-
void Scope::linkObject(const std::string &name, BaseObject::Ptr object)
64+
void Scope::linkObject(const std::string &name, AnyObject::Ptr object)
6465
{
6566
assert(object != nullptr);
6667

src/environment/Scope.hpp

Lines changed: 5 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@
88
*/
99

1010
#pragma once
11-
#include "BaseObject.hpp"
12-
#include <new>
11+
#include <memory>
1312
#include <string>
1413
#include <unordered_map>
1514
#include <vector>
@@ -28,30 +27,10 @@ class Scope
2827
/// Get a named object ("variable") in our scope or an outer scope. We work
2928
/// outwards from our scope to handle variable shadowing correctly. If the
3029
/// object is not found, return nullptr.
31-
BaseObject::Ptr getOptionalNamedObject(const std::string &name) const;
30+
std::shared_ptr<class AnyObject> getOptionalNamedObject(const std::string &name) const;
3231

3332
/// Similar to getOptionalObject but has a check to ensure pointer is valid.
34-
BaseObject::Ptr getNamedObject(const std::string &name) const;
35-
36-
/// Get an object from the scope and cast to a subclass.
37-
template <typename TObject>
38-
std::shared_ptr<TObject> getNamedObject(const std::string &name) const
39-
{
40-
auto objectPtr = getNamedObject(name);
41-
return std::static_pointer_cast<TObject>(objectPtr);
42-
}
43-
44-
template <typename TObject>
45-
std::shared_ptr<TObject> getOptionalNamedObject(const std::string &name) const
46-
{
47-
BaseObject::Ptr obj = getOptionalNamedObject(name);
48-
if (!obj)
49-
{
50-
return nullptr;
51-
}
52-
53-
return std::static_pointer_cast<TObject>(obj);
54-
}
33+
std::shared_ptr<class AnyObject> getNamedObject(const std::string &name) const;
5534

5635
/// Returns non-const reference to parent scope.
5736
inline Scope *parentScope() { return parent; }
@@ -60,13 +39,13 @@ class Scope
6039
void setParentScope(Scope *parent_) { parent = parent_; }
6140

6241
/// Create a link between a variable name and an object in this scope.
63-
void linkObject(const std::string &name, BaseObject::Ptr object);
42+
void linkObject(const std::string &name, std::shared_ptr<class AnyObject> object);
6443

6544
private:
6645
/// Stores a mapping from the variable name to a pointer to the object. These
6746
/// are only linked objects defined in this scope. This enables variable
6847
/// shadowing.
69-
std::unordered_map<std::string, BaseObject::Ptr> linkedObjectForName;
48+
std::unordered_map<std::string, std::shared_ptr<class AnyObject>> linkedObjectForName;
7049

7150
Scope *parent{nullptr};
7251
};

src/eucleia.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ int main(int argc, const char *argv[])
1919
CLIParser parser("eucleia");
2020

2121
parser.addFlagArg("--help", "display available options");
22-
parser.addFlagArg("--trace", "logs everything!");
22+
parser.addFlagArg("--trace", "logs everything!"); /* TODO: - enable user to set different log levels or disable */
2323

2424
parser.addPositionalArg("fileName");
2525
parser.parseArgs(argc, argv);

src/interpreter/EucleiaInterpreter.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,8 @@
66
//
77

88
#include "EucleiaInterpreter.hpp"
9-
#include "BaseObject.hpp"
9+
1010
#include "FileParser.hpp"
11-
#include "Objects.hpp"
1211
#include "Scope.hpp"
1312
#include <iostream>
1413

src/lexer/CharStream.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "Stringify.hpp"
1515
#include <algorithm>
1616
#include <cstring>
17+
#include <filesystem>
1718
#include <stdio.h>
1819
#include <stdlib.h>
1920

@@ -172,5 +173,5 @@ unsigned int CharStream::endCol(unsigned int lineNum) const
172173

173174
std::string CharStream::location() const
174175
{
175-
return eucleia::stringify("File \"%s\", Ln %d, Col %d", path.c_str(), line, col);
176+
return eucleia::stringify("(%s:%d:%d)", path.filename().c_str(), line, col);
176177
}

src/lexer/CharStream.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
*/
99

1010
#pragma once
11+
#include <filesystem>
1112
#include <string>
1213
#include <unordered_map>
1314

@@ -59,8 +60,7 @@ class CharStream
5960
private:
6061
unsigned int endCol(unsigned int lineNum) const;
6162

62-
63-
const std::string path;
63+
const std::filesystem::path path;
6464

6565
char *base{nullptr};
6666
char *ptr{nullptr};

src/lexer/Token.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/**
2+
* @file Token.cpp
3+
* @author Edward Palmer
4+
* @date 2025-05-24
5+
*
6+
* @copyright Copyright (c) 2025
7+
*
8+
*/
9+
10+
#include "Token.hpp"
11+
12+
13+
std::string Token::typeToString() const /* TODO: - more efficient to have a static maps and return a reference to string */
14+
{
15+
switch (_type)
16+
{
17+
case NotSet:
18+
return "NotSet";
19+
case EndOfFile:
20+
return "EndOfFile";
21+
case Punctuation:
22+
return "Punctuation";
23+
case Keyword:
24+
return "Keyword";
25+
case Variable:
26+
return "Variable";
27+
case String:
28+
return "String";
29+
case Operator:
30+
return "Operator";
31+
case Int:
32+
return "Int";
33+
case Float:
34+
return "Float";
35+
default:
36+
ThrowException("Unknown token type");
37+
}
38+
}

src/lexer/Token.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ class Token : public std::string
3131
Float
3232
};
3333

34+
std::string typeToString() const;
35+
3436
/* Constructors */
3537
Token(Type type) : _type(type) {}
3638
Token(std::string &value, Type type = NotSet) : std::string(value), _type(type) {}
@@ -115,4 +117,4 @@ Token Tokens::dequeue()
115117
pop();
116118

117119
return next;
118-
}
120+
}

src/lexer/Tokenizer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ Tokens Tokenizer::buildTokens(const std::string &path)
2424
while (!stream.isLast())
2525
{
2626
Token token = buildNextToken(stream);
27-
log().debug(stream.location() + ": " + token);
27+
log().debug("Parsed '" + token + "' => " + token.typeToString() + " " + stream.location());
2828

2929
if (token.type() != Token::EndOfFile)
3030
tokens.push(std::move(token));

src/nodes/AddVariableNode.cpp

Lines changed: 21 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,17 @@
88
*/
99

1010
#include "AddVariableNode.hpp"
11-
#include "ArrayObject.hpp"
12-
#include "FloatObject.hpp"
13-
#include "IntObject.hpp"
11+
#include "Exceptions.hpp"
1412
#include "ObjectFactory.hpp"
15-
#include "StringObject.hpp"
1613

14+
AddVariableNode::AddVariableNode(std::string name, AnyObject::Type type)
15+
: LookupVariableNode(std::move(name)),
16+
_variableType(type)
17+
{
18+
setType(NodeType::AddVariable);
19+
}
1720

18-
BaseObject::Ptr AddVariableNode::evaluate(Scope &scope)
21+
AnyObject::Ptr AddVariableNode::evaluate(Scope &scope)
1922
{
2023
/* TODO: - add support for functions (to enable passing to other functions, etc) */
2124
auto objectPtr = ObjectFactory::allocate(_variableType);
@@ -26,39 +29,25 @@ BaseObject::Ptr AddVariableNode::evaluate(Scope &scope)
2629

2730

2831
/// Type checking.
29-
bool AddVariableNode::passesAssignmentTypeCheck(const BaseObject &assignObject) const
32+
bool AddVariableNode::passesAssignmentTypeCheck(const AnyObject &assignObject) const
3033
{
31-
switch (_variableType)
32-
{
33-
case ObjectType::Int:
34-
return assignObject.isObjectType<IntObject>();
35-
case ObjectType::Float:
36-
return assignObject.isObjectType<FloatObject>();
37-
case ObjectType::Bool:
38-
return assignObject.isObjectType<BoolObject>();
39-
case ObjectType::String:
40-
return assignObject.isObjectType<StringObject>();
41-
case ObjectType::Array:
42-
return assignObject.isObjectType<ArrayObject>();
43-
default:
44-
return false;
45-
}
34+
return assignObject.isType(_variableType);
4635
}
4736

4837

4938
std::string AddVariableNode::description() const
5039
{
5140
switch (_variableType)
5241
{
53-
case ObjectType::Bool:
42+
case AnyObject::Bool:
5443
return "Bool";
55-
case ObjectType::Int:
44+
case AnyObject::Int:
5645
return "Int";
57-
case ObjectType::Float:
46+
case AnyObject::Float:
5847
return "Float";
59-
case ObjectType::String:
48+
case AnyObject::String:
6049
return "String";
61-
case ObjectType::Array:
50+
case AnyObject::Array:
6251
return "Array";
6352
default:
6453
return "Unknown";
@@ -68,50 +57,23 @@ std::string AddVariableNode::description() const
6857

6958
AddReferenceVariableNode::AddReferenceVariableNode(std::string referenceName_,
7059
std::string boundName_,
71-
ObjectType boundType_)
60+
AnyObject::Type boundType_)
7261
: AddVariableNode(boundName_, boundType_),
7362
referenceName(referenceName_)
7463
{
7564
}
7665

7766

78-
BaseObject::Ptr AddReferenceVariableNode::evaluate(Scope &scope)
67+
AnyObject::Ptr AddReferenceVariableNode::evaluate(Scope &scope)
7968
{
8069
// 1. Lookup the object associated with the variable name defined in this
8170
// scope or a parent scope (no issue with lifetimes such as to be bound
8271
// object going out of scope before our reference.
83-
BaseObject::Ptr boundObject = scope.getNamedObject(name());
84-
85-
// 2. Type checking. The type of the reference must match that of the bound
86-
// object.
87-
bool passesTypeChecking{false};
88-
89-
// TODO: - add type checking for classes and struct references.
90-
switch (_variableType)
91-
{
92-
case ObjectType::Int:
93-
passesTypeChecking = boundObject->isObjectType<IntObject>();
94-
break;
95-
case ObjectType::Float:
96-
passesTypeChecking = boundObject->isObjectType<FloatObject>();
97-
break;
98-
case ObjectType::String:
99-
passesTypeChecking = boundObject->isObjectType<StringObject>();
100-
break;
101-
case ObjectType::Bool:
102-
passesTypeChecking = boundObject->isObjectType<StringObject>();
103-
break;
104-
case ObjectType::Array:
105-
passesTypeChecking = boundObject->isObjectType<ArrayObject>();
106-
break;
107-
case ObjectType::Struct:
108-
case ObjectType::Class:
109-
default:
110-
passesTypeChecking = true;
111-
break; // No type checking currently!
112-
}
72+
AnyObject::Ptr boundObject = scope.getNamedObject(name());
11373

114-
if (!passesTypeChecking)
74+
// TODO: - this will not work for classes/structs since they could point to different types.
75+
// 2. Type checking. The type of the reference must match that of the bound object.
76+
if (!passesAssignmentTypeCheck(*boundObject))
11577
{
11678
ThrowException("Cannot bind reference " + referenceName + " to variable " + name() + ". Types do not match!");
11779
}

0 commit comments

Comments
 (0)