Skip to content

Commit

Permalink
19861: Adds more warnings for when source code has parse errors (#111)
Browse files Browse the repository at this point in the history
  • Loading branch information
howsohazard authored Apr 4, 2024
1 parent 8a30212 commit 0c12c69
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 17 deletions.
10 changes: 2 additions & 8 deletions src/Amalgam/AssetManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,7 @@ EvaluableNodeReference AssetManager::LoadResourcePath(std::string &resource_path
code.erase(0, 3);
}

if(!debugSources)
return Parser::Parse(code, enm);
else
return Parser::Parse(code, enm, &resource_path);
return Parser::Parse(code, enm, &resource_path, debugSources);
}
else if(file_type == FILE_EXTENSION_JSON)
return EvaluableNodeReference(EvaluableNodeJSONTranslation::Load(processed_resource_path, enm, status), true);
Expand All @@ -94,10 +91,7 @@ EvaluableNodeReference AssetManager::LoadResourcePath(std::string &resource_path
if(strings.size() == 0)
return EvaluableNodeReference::Null();

if(!debugSources)
return Parser::Parse(strings[0], enm);
else
return Parser::Parse(strings[0], enm, &resource_path);
return Parser::Parse(strings[0], enm, &resource_path, debugSources);
}
else //just load the file as a string
{
Expand Down
2 changes: 1 addition & 1 deletion src/Amalgam/Opcodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -646,7 +646,7 @@ inline std::string GetStringFromEvaluableNodeType(EvaluableNodeType t, bool get_
inline EvaluableNodeType GetEvaluableNodeTypeFromString(const std::string &s, bool get_non_keywords = false)
{
auto sid = string_intern_pool.GetIDFromString(s);
if(sid == string_intern_pool.NOT_A_STRING_ID)
if(sid == string_intern_pool.NOT_A_STRING_ID || sid == string_intern_pool.EMPTY_STRING_ID)
return ENT_NOT_A_BUILT_IN_TYPE;

return GetEvaluableNodeTypeFromStringId(sid);
Expand Down
27 changes: 24 additions & 3 deletions src/Amalgam/Parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Parser::Parser()
pos = 0;
lineNumber = 0;
lineStartPos = 0;
numOpenParenthesis = 0;
}

std::string Parser::Backslashify(const std::string &s)
Expand Down Expand Up @@ -56,7 +57,8 @@ std::string Parser::Backslashify(const std::string &s)
return b;
}

EvaluableNodeReference Parser::Parse(std::string &code_string, EvaluableNodeManager *enm, std::string *original_source)
EvaluableNodeReference Parser::Parse(std::string &code_string, EvaluableNodeManager *enm,
std::string *original_source, bool debug_sources)
{
Parser pt;
pt.code = &code_string;
Expand All @@ -80,8 +82,18 @@ EvaluableNodeReference Parser::Parse(std::string &code_string, EvaluableNodeMana
}
}

pt.debugSources = debug_sources;

EvaluableNode *parse_tree = pt.ParseNextBlock();

if(!pt.originalSource.empty())
{
if(pt.numOpenParenthesis > 0)
std::cerr << "Warning: " << pt.numOpenParenthesis << " missing parenthesis in " << pt.originalSource << std::endl;
else if(pt.numOpenParenthesis < 0)
std::cerr << "Warning: " << -pt.numOpenParenthesis << " extra parenthesis in " << pt.originalSource << std::endl;
}

pt.PreevaluateNodes();
EvaluableNodeManager::UpdateFlagsForNodeTree(parse_tree);

Expand Down Expand Up @@ -291,7 +303,7 @@ void Parser::SkipWhitespaceAndAccumulateAttributes(EvaluableNode *target)
}

//if labeling source, prepend as comment
if(originalSource.size() > 0)
if(debugSources)
{
std::string new_comment = sourceCommentPrefix;
new_comment += std::to_string(lineNumber);
Expand Down Expand Up @@ -420,6 +432,7 @@ EvaluableNode *Parser::GetNextToken(EvaluableNode *new_token)
if(cur_char == '(') //identifier as command
{
pos++;
numOpenParenthesis++;
SkipWhitespaceAndAccumulateAttributes(new_token);
if(pos >= code->size())
{
Expand All @@ -433,14 +446,18 @@ EvaluableNode *Parser::GetNextToken(EvaluableNode *new_token)
if(IsEvaluableNodeTypeValid(new_token->GetType()))
return new_token;

//unspecified command, store the identifier in the string
//invalid opcode, warn if possible and store the identifier as a string
if(!originalSource.empty())
std::cerr << "Warning: " << " Invalid opcode at line " << lineNumber << " of " << originalSource << std::endl;

new_token->SetType(ENT_STRING, evaluableNodeManager, false);
new_token->SetStringValue(token);
return new_token;
}
else if(cur_char == ')')
{
pos++; //skip closing parenthesis
numOpenParenthesis--;
FreeNode(new_token);
return nullptr;
}
Expand Down Expand Up @@ -575,7 +592,11 @@ EvaluableNode *Parser::ParseNextBlock()

//if specifying something unusual, then assume it's just a null
if(n->GetType() == ENT_NOT_A_BUILT_IN_TYPE)
{
n->SetType(ENT_NULL, evaluableNodeManager);
if(!originalSource.empty())
std::cerr << "Warning: " << " Invalid opcode at line " << lineNumber << " of " << originalSource << std::endl;
}
}

}
Expand Down
12 changes: 10 additions & 2 deletions src/Amalgam/Parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,10 @@ class Parser
}

//Parses the code string and returns a tree of EvaluableNodeReference that represents the code
//if original_source a valid string, will prepend each node with a comment indicating original source
static EvaluableNodeReference Parse(std::string &code_string, EvaluableNodeManager *enm, std::string *original_source = nullptr);
//if original_source is a valid string, it will emit any warnings to stderr
//if debug_sources is true, it will prepend each node with a comment indicating original source
static EvaluableNodeReference Parse(std::string &code_string, EvaluableNodeManager *enm,
std::string *original_source = nullptr, bool debug_sources = false);

//Returns a string that represents the tree
// if expanded_whitespace, will emit additional whitespace to make it easier to read
Expand Down Expand Up @@ -187,9 +189,15 @@ class Parser
//Position at the start of the current line
size_t lineStartPos;

//number of currently open parenthesis
int64_t numOpenParenthesis;

//Original source (e.g., file if applicable)
std::string originalSource;

//if true, will prepend debug sources to node comments
bool debugSources;

//contains a list of nodes that need to be preevaluated on parsing
std::vector<EvaluableNode *> preevaluationNodes;

Expand Down
5 changes: 2 additions & 3 deletions src/Amalgam/amlg_code/test.amlg
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
(seq
(create_entities "MergeEntity1" (lambda (associate "a" 3 "b" 4)) )
(print (retrieve_entity_root (list) ))
(seeq
(a)
)

0 comments on commit 0c12c69

Please sign in to comment.