Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adapt nyan to new specification #84

Closed
wants to merge 71 commits into from
Closed
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
ef6cf3b
lexer: Add '!' (bang) as symbol.
heinezen Oct 5, 2020
ec687e0
lexer: Enforce 'version' as first argument in file.
heinezen Oct 6, 2020
e017655
lexer: Fix dates and include dict type.
heinezen Oct 12, 2020
05f74f6
parser: Read arbitrary member type arguments.
heinezen Oct 16, 2020
1083219
nyan: Allow floats for int operations.
heinezen Oct 17, 2020
d075d25
nyan: Define values for float/int positive and negative infinty.
heinezen Oct 17, 2020
c9a9daa
nyan: Calculus rules for infinity.
heinezen Oct 18, 2020
d2a9005
lexer: Parse inf/-inf tokens.
heinezen Oct 19, 2020
e29f7d4
nyan: Fix handling infinity pointer.
heinezen Oct 19, 2020
8e902ec
nyan: Change bool's True/False to pythonic notation.
heinezen Oct 19, 2020
0b873cf
nyan: ValueToken for more complex values.
heinezen Oct 24, 2020
096317c
nyan: Use ValueToken while creating AST and Value instances.
heinezen Oct 25, 2020
c1b62b5
parser: Parse dict items.
heinezen Oct 25, 2020
32df34b
nyan: Dict data type.
heinezen Oct 27, 2020
6b19fab
nyan: Make 'element_type' of Type a vector.
heinezen Nov 22, 2020
6902201
dict: Create dicts from nyan file.
heinezen Nov 22, 2020
4b005dd
dict: Intersection operation.
heinezen Nov 23, 2020
80ea0e9
dict: Iterator logic.
heinezen Nov 25, 2020
f4000a4
refactor: Rename container types to composite types. Include type mod…
heinezen Nov 26, 2020
5995d04
parser: Allow limiting the number of read elements in comma_list().
heinezen Nov 28, 2020
4497163
parser: Allow nested types.
heinezen Nov 28, 2020
5090faf
init: New function for extracting value from ValueToken.
heinezen Dec 11, 2020
28465f5
nyan: Check for "None" value.
heinezen Dec 11, 2020
436071b
nyan: None value.
heinezen Dec 12, 2020
2eee390
nyan: Check modifiers.
heinezen Dec 12, 2020
6d02965
refactor: Add comments to ast.h.
heinezen Dec 12, 2020
1af9713
refactor: Add comments to api_error.h.
heinezen Dec 16, 2020
f1a190e
refactor: Add comments to basic_type.h.
heinezen Dec 16, 2020
fee9488
refactor: Add comments to c3.h.
heinezen Dec 16, 2020
78cd996
refactor: Add comments to change_tracker.h.
heinezen Dec 16, 2020
aeeaa1b
refactor: Add comments to curve.h.
heinezen Dec 16, 2020
d1c52d9
refactor: Add comments to database.h.
heinezen Dec 16, 2020
9c2a7fe
refactor: Add comments to error.h.
heinezen Dec 16, 2020
06212ba
refactor: Add comments to file.h.
heinezen Dec 16, 2020
ecbb66f
refactor: Add comments to id_token.h.
heinezen Dec 16, 2020
ef2bf3a
refactor: Add comments to inheritance_change.h.
heinezen Dec 16, 2020
458bb5e
refactor: Add comments to lang_error.h.
heinezen Dec 16, 2020
9a4c8ab
refactor: Add comments to location.h.
heinezen Dec 16, 2020
6358d0e
refactor: Add comments to member_info.h.
heinezen Dec 19, 2020
36af270
refactor: Add comments to member.h.
heinezen Dec 19, 2020
312914b
refactor: Add comments to meta_info.h.
heinezen Dec 19, 2020
6756dc1
refactor: Add comments to namespace_finder.h.
heinezen Dec 20, 2020
d139bab
refactor: Add comments to namespace.h.
heinezen Dec 20, 2020
a54937e
refactor: Add comments to object_history.h.
heinezen Dec 20, 2020
bf5db02
refactor: Add comments to object_info.h.
heinezen Dec 20, 2020
4025fff
refactor: Add comments to object_notifier.h.
heinezen Dec 20, 2020
5ed8e63
refactor: Add comments to object_state.h.
heinezen Dec 20, 2020
d48c873
refactor: Add comments to object.h.
heinezen Dec 20, 2020
a345388
refactor: Add comments to ops.h.
heinezen Dec 20, 2020
492d730
refactor: Add comments to parser.h.
heinezen Dec 20, 2020
c6e080a
refactor: Add comments to patch_info.h.
heinezen Dec 20, 2020
0f79321
refactor: Add comments to state_history.h.
heinezen Dec 20, 2020
9122237
refactor: Add comments to state.h.
heinezen Dec 20, 2020
543478d
refactor: Add comments to token_stream.h.
heinezen Dec 20, 2020
8ba7e7a
refactor: Add comments to token.h.
heinezen Dec 20, 2020
549855c
refactor: Add comments to transaction.h.
heinezen Dec 21, 2020
ba2cdfc
refactor: Add comments to type.h.
heinezen Dec 21, 2020
7d5dfaa
refactor: Add comments to util.h.
heinezen Dec 21, 2020
22b1725
refactor: Add comments to value_token.h.
heinezen Dec 21, 2020
8fd9b9e
refactor: Add comments to value.h.
heinezen Dec 21, 2020
ccae9c0
refactor: Add comments to value_holder.h.
heinezen Dec 21, 2020
bb3dfd4
refactor: Convert tabs to spaces in files.
heinezen Dec 21, 2020
1a092e3
fix copyright dates.
heinezen Dec 21, 2020
90097df
nyan: Assign None directly on Member::apply().
heinezen Dec 23, 2020
3cb82d7
parser: Use switch statement for differentiating composite types.
heinezen Jan 15, 2021
590c268
dict: Comment fixes.
heinezen Jan 15, 2021
2831c7e
ast: Use size_t for comma list boundary.
heinezen Jan 15, 2021
a83907e
nyan: Cody styling for is_none() function.
heinezen Jan 15, 2021
8e537c9
nyan: Remove unused parameters from lambda functions.
heinezen Jan 15, 2021
b8952bf
nyan: Better description for None.
heinezen Jan 15, 2021
72f5e03
parser: Replace ifs in handle_modifiers() with switch statement.
heinezen Jan 15, 2021
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
144 changes: 123 additions & 21 deletions nyan/ast.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2016-2019 the nyan authors, LGPLv3+. See copying.md for legal info.
// Copyright 2016-2020 the nyan authors, LGPLv3+. See copying.md for legal info.

#include "ast.h"

Expand Down Expand Up @@ -61,6 +61,11 @@ std::string ASTBase::str() const {
}


const std::vector<ASTArgument> &AST::get_args() const {
return this->args;
}


const std::vector<ASTObject> &AST::get_objects() const {
return this->objects;
}
Expand All @@ -72,9 +77,27 @@ const std::vector<ASTImport> &AST::get_imports() const {


AST::AST(TokenStream &tokens) {
auto token = tokens.next();

// Ensure that AST has version argument
if (token->type == token_type::BANG) {
this->args.emplace_back(tokens);

if (this->args.front().get_arg().str() != "version") {
throw InternalError{"file must start with 'version' argument, not "
+ this->args.front().get_arg().str()};
}
}
else {
throw InternalError{"missing starting argument: version"};
}

while (tokens.full()) {
auto token = tokens.next();
if (token->type == token_type::IMPORT) {
token = tokens.next();
if (token->type == token_type::BANG) {
this->args.emplace_back(tokens);
}
else if (token->type == token_type::IMPORT) {
this->imports.emplace_back(tokens);
}
else if (token->type == token_type::ID) {
Expand All @@ -96,6 +119,37 @@ AST::AST(TokenStream &tokens) {
}


ASTArgument::ASTArgument(TokenStream &tokens) {
auto token = tokens.next();

if (token->type == token_type::ID) {
this->arg = IDToken{*token, tokens};
token = tokens.next();
} else {
throw ASTError("expected argument keyword, encountered", *token);
}

while (not token->is_endmarker()) {
if (token->is_content()) {
this->params.emplace_back(*token, tokens);
token = tokens.next();
} else {
throw ASTError("expected parameter value, encountered", *token);
}
}
}


const IDToken &ASTArgument::get_arg() const {
return this->arg;
}


const std::vector<IDToken> &ASTArgument::get_params() const {
return this->params;
}


ASTImport::ASTImport(TokenStream &tokens) {
auto token = tokens.next();

Expand Down Expand Up @@ -448,33 +502,30 @@ ASTMember::ASTMember(const Token &name,
ASTMemberType::ASTMemberType()
:
does_exist{false},
has_payload{false} {}
has_args{false} {}


ASTMemberType::ASTMemberType(const Token &name,
TokenStream &tokens)
:
does_exist{true},
has_payload{false} {
has_args{false} {

this->name = IDToken{name, tokens};

// now there may follow a type payload, e.g. set(payloadtype)
// now there may follow type arguments, e.g. set(arg, key=val)
auto token = tokens.next();
if (token->type == token_type::LPAREN) {
token = tokens.next();
if (token->type == token_type::ID) {
this->payload = IDToken{*token, tokens};
this->has_payload = true;
}
else {
throw ASTError("expected type identifier, but got", *token);
}

token = tokens.next();

if (token->type != token_type::RPAREN) {
throw ASTError("expected closing parens, but encountered", *token);
comma_list(
token_type::RPAREN,
tokens,
[this] (const Token & /*token*/, TokenStream &stream) {
stream.reinsert_last();
this->args.emplace_back(stream);
}
);
if (this->args.size() > 0) {
this->has_args = true;
}
} else {
tokens.reinsert_last();
Expand All @@ -487,6 +538,36 @@ bool ASTMemberType::exists() const {
}


ASTMemberTypeArgument::ASTMemberTypeArgument(TokenStream &tokens)
:
has_key{false} {
auto token = tokens.next();
if (token->type != token_type::ID) {
throw ASTError("expected argument value or key, but got", *token);
}

auto next_token = tokens.next();
// check if the argument is keyed
if (next_token->type == token_type::OPERATOR) {
if (unlikely(op_from_token(*next_token) != nyan_op::ASSIGN)) {
throw ASTError("expected argument keyed assignment, but got", *token);
}

this->has_key = true;
this->key = IDToken(*token, tokens);

token = tokens.next();
if (unlikely(token->type != token_type::ID)) {
throw ASTError("expected argument value, but got", *token);
}
} else {
tokens.reinsert_last();
}

this->value = IDToken{*token, tokens};
}


ASTMemberValue::ASTMemberValue()
:
does_exist{false} {}
Expand All @@ -512,6 +593,7 @@ ASTMemberValue::ASTMemberValue(container_t type,
switch (this->container_type) {
case container_t::SET:
case container_t::ORDEREDSET:
case container_t::DICT:
end_token = token_type::RBRACE; break;

default:
Expand Down Expand Up @@ -560,6 +642,12 @@ void AST::strb(std::ostringstream &builder, int indentlevel) const {
}
}

void ASTArgument::strb(std::ostringstream &builder, int /*indentlevel*/) const {
builder << "!" << this->arg.str();
for (auto &param : this->params) {
builder << " " << param.str();
}
}

void ASTImport::strb(std::ostringstream &builder, int /*indentlevel*/) const {
builder << "import " << this->namespace_name.str();
Expand Down Expand Up @@ -658,19 +746,32 @@ void ASTMember::strb(std::ostringstream &builder, int indentlevel) const {
void ASTMemberType::strb(std::ostringstream &builder, int /*indentlevel*/) const {
builder << this->name.str();

if (this->has_payload) {
builder << "(" << this->payload.str() << ")";
if (this->has_args) {
builder << "(";
for (auto &arg : this->args) {
arg.strb(builder);
}
builder << ")";
}
}


void ASTMemberTypeArgument::strb(std::ostringstream &builder, int /*indentlevel*/) const {
if (this->has_key) {
builder << this->key.str() << "=";
}

builder << this->value.str();
}

void ASTMemberValue::strb(std::ostringstream &builder, int /*indentlevel*/) const {
switch (this->container_type) {
case container_t::SINGLE:
builder << this->values[0].str();
return;

case container_t::SET:
case container_t::DICT:
builder << "{"; break;

case container_t::ORDEREDSET:
Expand All @@ -692,6 +793,7 @@ void ASTMemberValue::strb(std::ostringstream &builder, int /*indentlevel*/) cons
switch (this->container_type) {
case container_t::SET:
case container_t::ORDEREDSET:
case container_t::DICT:
builder << "}"; break;

default:
Expand Down
51 changes: 47 additions & 4 deletions nyan/ast.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2016-2019 the nyan authors, LGPLv3+. See copying.md for legal info.
// Copyright 2016-2020 the nyan authors, LGPLv3+. See copying.md for legal info.
#pragma once


Expand Down Expand Up @@ -47,6 +47,26 @@ class ASTBase {
};


/**
* AST representation of a member type argument declaration.
*/
class ASTMemberTypeArgument : public ASTBase {
friend class ASTMemberType;
friend class Database;
friend class Type;

public:
ASTMemberTypeArgument(TokenStream &tokens);

void strb(std::ostringstream &builder, int indentlevel=0) const override;

protected:
bool has_key;
IDToken key;
IDToken value;
};


/**
* AST representation of a member type declaration.
*/
Expand All @@ -65,8 +85,8 @@ class ASTMemberType : ASTBase {
bool does_exist;
IDToken name;

bool has_payload;
IDToken payload;
bool has_args;
std::vector<ASTMemberTypeArgument> args;
};


Expand Down Expand Up @@ -116,6 +136,27 @@ class ASTMember : public ASTBase {
};


/**
* The abstract syntax tree representation of an argument.
*/
class ASTArgument : public ASTBase {
public:
ASTArgument(TokenStream &tokens);

void strb(std::ostringstream &builder, int indentlevel=0) const override;

/** return the argument */
const IDToken &get_arg() const;

/** return the parameters */
const std::vector<IDToken> &get_params() const;

protected:
IDToken arg;
std::vector<IDToken> params;
};


/**
* An import in a nyan file is represented by this AST entry.
* Used for the `import ... (as ...)` statement.
Expand All @@ -142,7 +183,7 @@ class ASTImport : public ASTBase {


/**
* Inheritance chang
* Inheritance change
*/
class ASTInheritanceChange : public ASTBase {
friend class Database;
Expand Down Expand Up @@ -196,10 +237,12 @@ class AST : public ASTBase {
AST(TokenStream &tokens);

void strb(std::ostringstream &builder, int indentlevel=0) const override;
const std::vector<ASTArgument> &get_args() const;
const std::vector<ASTObject> &get_objects() const;
const std::vector<ASTImport> &get_imports() const;

protected:
std::vector<ASTArgument> args;
std::vector<ASTImport> imports;
std::vector<ASTObject> objects;
};
Expand Down
5 changes: 3 additions & 2 deletions nyan/basic_type.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2016-2018 the nyan authors, LGPLv3+. See copying.md for legal info.
// Copyright 2016-2020 the nyan authors, LGPLv3+. See copying.md for legal info.

#include "basic_type.h"

Expand Down Expand Up @@ -56,7 +56,8 @@ BasicType BasicType::from_type_token(const IDToken &tok) {
// container type name map
static const std::unordered_map<std::string, container_t> container_types = {
{"set", container_t::SET},
{"orderedset", container_t::ORDEREDSET}
{"orderedset", container_t::ORDEREDSET},
{"dict", container_t::DICT}
};


Expand Down
4 changes: 3 additions & 1 deletion nyan/basic_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ enum class primitive_t {
INT,
FLOAT,
CONTAINER,
OBJECT
OBJECT,
};


Expand All @@ -34,6 +34,7 @@ enum class container_t {
SINGLE,
SET,
ORDEREDSET,
DICT,
};


Expand Down Expand Up @@ -122,6 +123,7 @@ constexpr const char *container_type_to_string(container_t type) {
case container_t::SINGLE: return "single_value";
case container_t::SET: return "set";
case container_t::ORDEREDSET: return "orderedset";
case container_t::DICT: return "dict";
}

return "unhandled container_t";
Expand Down
11 changes: 11 additions & 0 deletions nyan/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,16 @@ using value_int_t = int64_t;
/** type used for nyan::Float values */
using value_float_t = double;

/** positive infinity for nyan::Int values */
constexpr const value_int_t INT_POS_INF = std::numeric_limits<value_int_t>::max();

/** negative infinity for nyan::Int values */
constexpr const value_int_t INT_NEG_INF = std::numeric_limits<value_int_t>::min();

/** positive infinity for nyan::Float values */
constexpr const value_float_t FLOAT_POS_INF = std::numeric_limits<value_float_t>::infinity();

/** negative infinity for nyan::Float values */
constexpr const value_float_t FLOAT_NEG_INF = -std::numeric_limits<value_float_t>::infinity();

} // namespace nyan
1 change: 1 addition & 0 deletions nyan/lexer/flex.lpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ float -?({digit}+\.{digit}*|{digit}*\.{digit}+)
"{" { impl->token(nyan::token_type::LBRACE); }
"}" { impl->token(nyan::token_type::RBRACE); }
"@" { impl->token(nyan::token_type::AT); }
"!" { impl->token(nyan::token_type::BANG); }

"pass" { impl->token(nyan::token_type::PASS); }
"..." { impl->token(nyan::token_type::ELLIPSIS); }
Expand Down
Loading