Add analysis of function declaration & prototype
This commit is contained in:
parent
4de0c57236
commit
ca02c78673
@ -264,6 +264,55 @@ AnalysisResult analyze(Node &ast, Memory &memory) {
|
|||||||
analyze(node.children[0], memory);
|
analyze(node.children[0], memory);
|
||||||
return analyze(node.children[1], memory);
|
return analyze(node.children[1], memory);
|
||||||
}
|
}
|
||||||
|
case NodeType::FunctionPrototype: {
|
||||||
|
Token return_type_token = get<Token>(node.children[0]);
|
||||||
|
string return_type_string = get<string>(return_type_token.data);
|
||||||
|
Type return_type = try_string_to_type(return_type_string, return_type_token.pos);
|
||||||
|
|
||||||
|
Token token = get<Token>(node.children[1]);
|
||||||
|
string function_name = get<string>(token.data);
|
||||||
|
|
||||||
|
try {
|
||||||
|
memory.get_function_scope();
|
||||||
|
throw RuntimeError(ErrorType::NestedFunction, token.pos, {});
|
||||||
|
} catch (const InternalError& _) {}
|
||||||
|
|
||||||
|
memory.declare(function_name, {
|
||||||
|
.type = TypeType::Function,
|
||||||
|
.data = make_fn_prototype(node)
|
||||||
|
}, return_type_token.pos);
|
||||||
|
|
||||||
|
return {};
|
||||||
|
} break;
|
||||||
|
case NodeType::FunctionDeclaration: {
|
||||||
|
Token return_type_token = get<Token>(node.children[0]);
|
||||||
|
string return_type_string = get<string>(return_type_token.data);
|
||||||
|
Type return_type = try_string_to_type(return_type_string, return_type_token.pos);
|
||||||
|
|
||||||
|
Token token = get<Token>(node.children[1]);
|
||||||
|
string function_name = get<string>(token.data);
|
||||||
|
|
||||||
|
try {
|
||||||
|
memory.get_function_scope();
|
||||||
|
throw RuntimeError(ErrorType::NestedFunction, token.pos, {});
|
||||||
|
} catch (const InternalError& _) {}
|
||||||
|
|
||||||
|
if (memory.contains(function_name) && memory.get(function_name).initialized)
|
||||||
|
throw RuntimeError(ErrorType::FunctionRedefinition, token.pos, function_name);
|
||||||
|
|
||||||
|
memory.declare(function_name, {
|
||||||
|
.type = TypeType::Function,
|
||||||
|
.data = make_fn_prototype(node)
|
||||||
|
}, return_type_token.pos);
|
||||||
|
|
||||||
|
memory.update(function_name, node.children[3]);
|
||||||
|
|
||||||
|
memory.add_scope(ScopeType::Function, token.pos, &memory.get(function_name));
|
||||||
|
analyze(node.children[3], memory);
|
||||||
|
memory.remove_scope();
|
||||||
|
|
||||||
|
return {};
|
||||||
|
} break;
|
||||||
default:
|
default:
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@ string UserError::get_message(void) const {
|
|||||||
case ErrorType::TypesNotComparable: return "Types not comparable";
|
case ErrorType::TypesNotComparable: return "Types not comparable";
|
||||||
case ErrorType::ExpectedIntegralType: return "Expression must have integral type";
|
case ErrorType::ExpectedIntegralType: return "Expression must have integral type";
|
||||||
case ErrorType::NestedFunction: return "Function definition is not allowed here";
|
case ErrorType::NestedFunction: return "Function definition is not allowed here";
|
||||||
|
case ErrorType::FunctionRedefinition: return "Redefinition of '"+get<string>(this->data)+"'";
|
||||||
case ErrorType::ExpectedArithmeticType: return "Expression must have arithmetic type";
|
case ErrorType::ExpectedArithmeticType: return "Expression must have arithmetic type";
|
||||||
case ErrorType::UnknownIdentifier: return "Unknown identifier '"+get<string>(this->data)+"'";
|
case ErrorType::UnknownIdentifier: return "Unknown identifier '"+get<string>(this->data)+"'";
|
||||||
case ErrorType::AlreadyDeclaredIdentifier: return "Already declared identifier '"+get<string>(this->data)+"'";
|
case ErrorType::AlreadyDeclaredIdentifier: return "Already declared identifier '"+get<string>(this->data)+"'";
|
||||||
|
@ -34,6 +34,7 @@ enum class ErrorType {
|
|||||||
ExpectedIntegralType,
|
ExpectedIntegralType,
|
||||||
ExpectedArithmeticType,
|
ExpectedArithmeticType,
|
||||||
NestedFunction,
|
NestedFunction,
|
||||||
|
FunctionRedefinition,
|
||||||
|
|
||||||
// Runtime
|
// Runtime
|
||||||
UnknownIdentifier,
|
UnknownIdentifier,
|
||||||
|
Loading…
Reference in New Issue
Block a user