Got simple type inference for declaration statements working with test
This commit is contained in:
@@ -19,6 +19,11 @@ class ASTTransformation: public NodeTransformation<Symbol,ASTData> {
|
|||||||
ASTTransformation(Importer* importerIn);
|
ASTTransformation(Importer* importerIn);
|
||||||
~ASTTransformation();
|
~ASTTransformation();
|
||||||
|
|
||||||
|
NodeTree<Symbol>* getNode(std::string lookup, std::vector<NodeTree<Symbol>*> nodes);
|
||||||
|
NodeTree<Symbol>* getNode(std::string lookup, NodeTree<Symbol>* parent);
|
||||||
|
std::vector<NodeTree<Symbol>*> getNodes(std::string lookup, std::vector<NodeTree<Symbol>*> nodes);
|
||||||
|
std::vector<NodeTree<Symbol>*> getNodes(std::string lookup, NodeTree<Symbol>* parent);
|
||||||
|
|
||||||
//First pass defines all type_defs (objects and ailises)
|
//First pass defines all type_defs (objects and ailises)
|
||||||
NodeTree<ASTData>* firstPass(std::string fileName, NodeTree<Symbol>* parseTree);
|
NodeTree<ASTData>* firstPass(std::string fileName, NodeTree<Symbol>* parseTree);
|
||||||
std::set<std::string> parseTraits(NodeTree<Symbol>* traitsNode);
|
std::set<std::string> parseTraits(NodeTree<Symbol>* traitsNode);
|
||||||
|
|||||||
@@ -104,7 +104,8 @@ number = integer | floating_literal ;
|
|||||||
access_operation = unarad "." identifier | unarad "->" identifier ;
|
access_operation = unarad "." identifier | unarad "->" identifier ;
|
||||||
|
|
||||||
assignment_statement = factor WS "=" WS boolean_expression | factor WS "\+=" WS boolean_expression | factor WS "-=" WS boolean_expression | factor WS "\*=" WS boolean_expression | factor WS "/=" WS boolean_expression ;
|
assignment_statement = factor WS "=" WS boolean_expression | factor WS "\+=" WS boolean_expression | factor WS "-=" WS boolean_expression | factor WS "\*=" WS boolean_expression | factor WS "/=" WS boolean_expression ;
|
||||||
declaration_statement = "var" WS identifier WS dec_type WS "=" WS boolean_expression | "var" WS identifier WS dec_type | "var" WS identifier WS "." WS identifier WS "\(" WS opt_parameter_list WS "\)" WS dec_type ;
|
# if it's being assigned to, we allow type inferencing
|
||||||
|
declaration_statement = "var" WS identifier WS "=" WS boolean_expression | "var" WS identifier WS dec_type WS "=" WS boolean_expression | "var" WS identifier WS dec_type | "var" WS identifier WS "." WS identifier WS "\(" WS opt_parameter_list WS "\)" WS dec_type ;
|
||||||
hexadecimal = "0x(1|2|3|4|5|6|7|8|9|a|b|c|d|e|f)+" ;
|
hexadecimal = "0x(1|2|3|4|5|6|7|8|9|a|b|c|d|e|f)+" ;
|
||||||
integer = numeric | hexadecimal ;
|
integer = numeric | hexadecimal ;
|
||||||
floating_literal = numeric "." numeric ;
|
floating_literal = numeric "." numeric ;
|
||||||
|
|||||||
@@ -39,6 +39,33 @@ ASTTransformation::ASTTransformation(Importer *importerIn) {
|
|||||||
ASTTransformation::~ASTTransformation() {
|
ASTTransformation::~ASTTransformation() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NodeTree<Symbol>* ASTTransformation::getNode(std::string lookup, NodeTree<Symbol>* parent) {
|
||||||
|
auto results = getNodes(lookup, parent);
|
||||||
|
if (results.size() > 1)
|
||||||
|
throw "too many results";
|
||||||
|
if (results.size())
|
||||||
|
return results[0];
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
NodeTree<Symbol>* ASTTransformation::getNode(std::string lookup, std::vector<NodeTree<Symbol>*> nodes) {
|
||||||
|
auto results = getNodes(lookup, nodes);
|
||||||
|
if (results.size() > 1)
|
||||||
|
throw "too many results";
|
||||||
|
if (results.size())
|
||||||
|
return results[0];
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
std::vector<NodeTree<Symbol>*> ASTTransformation::getNodes(std::string lookup, NodeTree<Symbol>* parent) {
|
||||||
|
return getNodes(lookup, parent->getChildren());
|
||||||
|
}
|
||||||
|
std::vector<NodeTree<Symbol>*> ASTTransformation::getNodes(std::string lookup, std::vector<NodeTree<Symbol>*> nodes) {
|
||||||
|
std::vector<NodeTree<Symbol>*> results;
|
||||||
|
for (auto i : nodes)
|
||||||
|
if (i->getDataRef()->getName() == lookup)
|
||||||
|
results.push_back(i);
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
//First pass defines all type_defs (objects and ailises), and if_comp/simple_passthrough
|
//First pass defines all type_defs (objects and ailises), and if_comp/simple_passthrough
|
||||||
NodeTree<ASTData>* ASTTransformation::firstPass(std::string fileName, NodeTree<Symbol>* parseTree) {
|
NodeTree<ASTData>* ASTTransformation::firstPass(std::string fileName, NodeTree<Symbol>* parseTree) {
|
||||||
NodeTree<ASTData>* translationUnit = new NodeTree<ASTData>("translation_unit", ASTData(translation_unit, Symbol(fileName, false)));
|
NodeTree<ASTData>* translationUnit = new NodeTree<ASTData>("translation_unit", ASTData(translation_unit, Symbol(fileName, false)));
|
||||||
@@ -580,20 +607,24 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
|
|||||||
// NodeTree<ASTData>* newIdentifier = transform(children[1], scope); //Transform the identifier
|
// NodeTree<ASTData>* newIdentifier = transform(children[1], scope); //Transform the identifier
|
||||||
// newIdentifier->getDataRef()->valueType = Type(concatSymbolTree(children[0]));//set the type of the identifier
|
// newIdentifier->getDataRef()->valueType = Type(concatSymbolTree(children[0]));//set the type of the identifier
|
||||||
std::string newIdentifierStr = concatSymbolTree(children[0]);
|
std::string newIdentifierStr = concatSymbolTree(children[0]);
|
||||||
Type* identifierType;
|
NodeTree<Symbol>* typeSyntaxNode = getNode("type", children);
|
||||||
if (children.size() > 1 && concatSymbolTree(children[1]) == ".")
|
Type* identifierType = typeSyntaxNode ? typeFromTypeNode(typeSyntaxNode, scope, templateTypeReplacements) : nullptr;
|
||||||
identifierType = typeFromTypeNode(children.back(), scope, templateTypeReplacements);
|
//if (children.size() > 1 && concatSymbolTree(children[1]) == ".")
|
||||||
else
|
//identifierType = typeFromTypeNode(children.back(), scope, templateTypeReplacements);
|
||||||
identifierType = typeFromTypeNode(children[2], scope, templateTypeReplacements);
|
//else
|
||||||
|
//identifierType = typeFromTypeNode(children[2], scope, templateTypeReplacements);
|
||||||
|
|
||||||
std::cout << "Declaring an identifier " << newIdentifierStr << " to be of type " << identifierType->toString() << std::endl;
|
if (identifierType)
|
||||||
NodeTree<ASTData>* newIdentifier = new NodeTree<ASTData>("identifier", ASTData(identifier, Symbol(newIdentifierStr, true), identifierType));
|
std::cout << "Declaring an identifier " << newIdentifierStr << " to be of type " << identifierType->toString() << std::endl;
|
||||||
addToScope(newIdentifierStr, newIdentifier, scope);
|
else
|
||||||
addToScope("~enclosing_scope", scope, newNode);
|
std::cout << "Declaring an identifier " << newIdentifierStr << " with type to be type-inferenced " << std::endl;
|
||||||
addToScope("~enclosing_scope", newNode, newIdentifier);
|
|
||||||
newNode->addChild(newIdentifier);
|
|
||||||
|
|
||||||
if (children.size() > 1 && concatSymbolTree(children[1]) == ".") {
|
if (children.size() > 1 && concatSymbolTree(children[1]) == ".") {
|
||||||
|
NodeTree<ASTData>* newIdentifier = new NodeTree<ASTData>("identifier", ASTData(identifier, Symbol(newIdentifierStr, true), identifierType));
|
||||||
|
addToScope(newIdentifierStr, newIdentifier, scope);
|
||||||
|
addToScope("~enclosing_scope", scope, newNode);
|
||||||
|
addToScope("~enclosing_scope", newNode, newIdentifier);
|
||||||
|
newNode->addChild(newIdentifier);
|
||||||
//A bit of a special case for declarations - if there's anything after just the normal 1 node declaration, it's either
|
//A bit of a special case for declarations - if there's anything after just the normal 1 node declaration, it's either
|
||||||
//an expression that is assigned to the declaration (int a = 4;) or a member call (Object a.constructAThing())
|
//an expression that is assigned to the declaration (int a = 4;) or a member call (Object a.constructAThing())
|
||||||
//This code is a simplified version of the code in function_call with respect to access_operation.
|
//This code is a simplified version of the code in function_call with respect to access_operation.
|
||||||
@@ -615,9 +646,28 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
|
|||||||
return newNode;
|
return newNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
skipChildren.insert(0); //These, the type and the identifier, have been taken care of.
|
//skipChildren.insert(0); //These, the type and the identifier, have been taken care of.
|
||||||
skipChildren.insert(2);
|
//skipChildren.insert(2);
|
||||||
newNode->addChildren(transformChildren(children, skipChildren, scope, types, templateTypeReplacements));
|
//auto transChildren = transformChildren(children, skipChildren, scope, types, templateTypeReplacements);
|
||||||
|
auto boolExp = getNode("boolean_expression", children);
|
||||||
|
NodeTree<ASTData>* toAssign = boolExp ? transform(boolExp, scope, types, templateTypeReplacements) : nullptr;
|
||||||
|
// for type inferencing
|
||||||
|
if (!identifierType) {
|
||||||
|
if (toAssign)
|
||||||
|
identifierType = toAssign->getDataRef()->valueType;
|
||||||
|
else
|
||||||
|
throw "have to inference but no expression";
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeTree<ASTData>* newIdentifier = new NodeTree<ASTData>("identifier", ASTData(identifier, Symbol(newIdentifierStr, true), identifierType));
|
||||||
|
addToScope(newIdentifierStr, newIdentifier, scope);
|
||||||
|
addToScope("~enclosing_scope", scope, newNode);
|
||||||
|
addToScope("~enclosing_scope", newNode, newIdentifier);
|
||||||
|
|
||||||
|
newNode->addChild(newIdentifier);
|
||||||
|
if (toAssign)
|
||||||
|
newNode->addChild(toAssign);
|
||||||
|
//newNode->addChildren(transChildren);
|
||||||
return newNode;
|
return newNode;
|
||||||
} else if (name == "if_comp") {
|
} else if (name == "if_comp") {
|
||||||
newNode = new NodeTree<ASTData>(name, ASTData(if_comp));
|
newNode = new NodeTree<ASTData>(name, ASTData(if_comp));
|
||||||
|
|||||||
10
tests/test_typeInfr.expected_results
Normal file
10
tests/test_typeInfr.expected_results
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
hello
|
||||||
|
9
|
||||||
|
27
|
||||||
|
12
|
||||||
|
9.300000
|
||||||
|
I do like type inference
|
||||||
|
11
|
||||||
|
9
|
||||||
|
80
|
||||||
|
complicated
|
||||||
51
tests/test_typeInfr.krak
Normal file
51
tests/test_typeInfr.krak
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
import io:*
|
||||||
|
import mem:*
|
||||||
|
import vector:*
|
||||||
|
|
||||||
|
fun retMessage(): char* {
|
||||||
|
return "I do like type inference"
|
||||||
|
}
|
||||||
|
fun id<T>(in: T): T { return in; }
|
||||||
|
|
||||||
|
typedef CustomObj {
|
||||||
|
var data: int;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef CustomObjTmplt<T> {
|
||||||
|
var data: T;
|
||||||
|
}
|
||||||
|
fun inFun<T>(in: T):T {
|
||||||
|
var src: CustomObjTmplt<T>
|
||||||
|
src.data = in
|
||||||
|
var dst = src
|
||||||
|
return dst.data
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main():int {
|
||||||
|
var str = "hello"
|
||||||
|
var avar = 9
|
||||||
|
var mul = 9 * 3
|
||||||
|
var add = 9 + 3
|
||||||
|
var flt = 9.3
|
||||||
|
var msg = retMessage()
|
||||||
|
var fromTemplateFun = id<int>(11);
|
||||||
|
var vec = new<vector<int>>()->construct()
|
||||||
|
vec->addEnd(avar)
|
||||||
|
|
||||||
|
var src: CustomObj
|
||||||
|
src.data = 80
|
||||||
|
var dst = src
|
||||||
|
var throughTemp = inFun<char*>("complicated");
|
||||||
|
|
||||||
|
println(str)
|
||||||
|
println(avar)
|
||||||
|
println(mul)
|
||||||
|
println(add)
|
||||||
|
println(flt)
|
||||||
|
println(msg)
|
||||||
|
println(fromTemplateFun)
|
||||||
|
println(vec->at(0))
|
||||||
|
println(dst.data)
|
||||||
|
println(throughTemp)
|
||||||
|
return 0
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user