Added Type class, bettered types a bit, made address of and dereference operators work.

This commit is contained in:
Nathan Braswell
2013-12-23 01:26:24 -06:00
parent 935cc6f968
commit 15674fec2a
10 changed files with 207 additions and 106 deletions

View File

@@ -4,12 +4,12 @@ ASTData::ASTData() {
this->type = undef;
}
ASTData::ASTData(ASTType type, ValueType valueType) {
ASTData::ASTData(ASTType type, Type valueType) {
this->type = type;
this->valueType = valueType;
}
ASTData::ASTData(ASTType type, Symbol symbol, ValueType valueType) {
ASTData::ASTData(ASTType type, Symbol symbol, Type valueType) {
this->type = type;
this->valueType = valueType;
this->symbol = symbol;
@@ -20,44 +20,7 @@ ASTData::~ASTData() {
}
std::string ASTData::toString() {
return ASTTypeToString(type) + (symbol.isTerminal() ? " " + symbol.toString() : "") + (valueType ? " " + ValueTypeToString(valueType) : "");
}
ValueType ASTData::strToType(std::string type) {
if (type == "void")
return void_type;
else if (type == "bool")
return boolean;
else if (type == "int")
return integer;
else if (type == "float")
return floating;
else if (type == "double")
return double_percision;
else if (type == "string")
return char_string;
else return none;
}
std::string ASTData::ValueTypeToString(ValueType type) {
switch (type) {
case none:
return "none";
case void_type:
return "void";
case boolean:
return "bool";
case integer:
return "int";
case floating:
return "float";
case double_percision:
return "double";
case char_string:
return "string";
default:
return "unknown_ValueType";
}
return ASTTypeToString(type) + (symbol.isTerminal() ? " " + symbol.toString() : "") + " " + valueType.toString();
}
std::string ASTData::ASTTypeToString(ASTType type) {

View File

@@ -25,14 +25,14 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from) {
} else if (name == "identifier") {
newNode = new NodeTree<ASTData>(name, ASTData(identifier, Symbol(concatSymbolTree(children[0]), true)));
} else if (name == "function") {
newNode = new NodeTree<ASTData>(name, ASTData(function, Symbol(concatSymbolTree(children[1]), true), ASTData::strToType(concatSymbolTree(children[0]))));
newNode = new NodeTree<ASTData>(name, ASTData(function, Symbol(concatSymbolTree(children[1]), true), Type(concatSymbolTree(children[0]))));
skipChildren.insert(0);
skipChildren.insert(1);
} else if (name == "code_block") {
newNode = new NodeTree<ASTData>(name, ASTData(code_block));
} else if (name == "typed_parameter") {
newNode = transform(children[1]); //Transform to get the identifier
newNode->getDataRef()->valueType = ASTData::strToType(concatSymbolTree(children[0])); //Get the type (left child) and set our new identifer to be that type
newNode->getDataRef()->valueType = Type(concatSymbolTree(children[0])); //Get the type (left child) and set our new identifer to be that type
return newNode;
} else if (name == "boolean_expression") {
//If this is an actual part of an expression, not just a premoted term
@@ -62,16 +62,31 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from) {
return transform(children[0]); //Just a promoted bool_exp, so do child
}
//Here's the order of ops stuff
} else if (name == "expression" || name == "shiftand" || name == "term" || name == "factor" || name == "unarad") {
} else if (name == "expression" || name == "shiftand" || name == "term" || name == "unarad") { //unarad can ride through, it should always just be a promoted child
//If this is an actual part of an expression, not just a premoted child
if (children.size() > 1) {
if (children.size() > 2) {
std::string functionCallName = concatSymbolTree(children[1]);
std::cout << functionCallName << std::endl;
newNode = new NodeTree<ASTData>(functionCallName, ASTData(function_call, Symbol(functionCallName, true)));
skipChildren.insert(1);
} else {
return transform(children[0]); //Just a promoted child, so do it instead
}
} else if (name == "factor") { //Do factor here, as it has all the weird unary operators
//If this is an actual part of an expression, not just a premoted child
//NO SUPPORT FOR CASTING YET
if (children.size() == 2) {
std::string funcName = concatSymbolTree(children[0]);
int funcNum;
if (funcName == "*" || funcName == "&" || funcName == "++" || funcName == "--" || funcName == "-" || funcName == "!" || funcName == "~")
funcNum = 0;
else
funcName = concatSymbolTree(children[1]), funcNum = 1;
newNode = new NodeTree<ASTData>(funcName, ASTData(function_call, Symbol(funcName, true)));
skipChildren.insert(funcNum);
} else {
return transform(children[0]); //Just a promoted child, so do it instead
}
} else if (name == "statement") {
newNode = new NodeTree<ASTData>(name, ASTData(statement));
} else if (name == "if_statement") {
@@ -101,7 +116,7 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from) {
} else if (name == "declaration_statement") {
newNode = new NodeTree<ASTData>(name, ASTData(declaration_statement));
NodeTree<ASTData>* newIdentifier = transform(children[1]); //Transform the identifier
newIdentifier->getDataRef()->valueType = ASTData::strToType(concatSymbolTree(children[0]));//set the type of the identifier
newIdentifier->getDataRef()->valueType = Type(concatSymbolTree(children[0]));//set the type of the identifier
newNode->addChild(newIdentifier);
skipChildren.insert(0); //These, the type and the identifier, have been taken care of.
skipChildren.insert(1);
@@ -116,18 +131,23 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from) {
skipChildren.insert(1);
} else if (name == "parameter") {
return transform(children[0]); //Don't need a parameter node, just the value
} else if (name == "bool") {
newNode = new NodeTree<ASTData>(name, ASTData(value, Symbol(concatSymbolTree(children[0]), true), boolean));
} else if (name == "parameter") {
return transform(children[0]); //Don't need a parameter node, just the value
} else if (name == "type") {
std::string theConcat = concatSymbolTree(from); //We have no symbol, so this will concat our children
newNode = new NodeTree<ASTData>(name, ASTData(value, Symbol(theConcat, true), Type(theConcat)));
} else if (name == "number") {
return transform(children[0]);
} else if (name == "integer") {
newNode = new NodeTree<ASTData>(name, ASTData(value, Symbol(concatSymbolTree(from), true), integer));
newNode = new NodeTree<ASTData>(name, ASTData(value, Symbol(concatSymbolTree(from), true), Type(integer)));
} else if (name == "float") {
newNode = new NodeTree<ASTData>(name, ASTData(value, Symbol(concatSymbolTree(from), true), floating));
newNode = new NodeTree<ASTData>(name, ASTData(value, Symbol(concatSymbolTree(from), true), Type(floating)));
} else if (name == "double") {
newNode = new NodeTree<ASTData>(name, ASTData(value, Symbol(concatSymbolTree(from), true), double_percision));
newNode = new NodeTree<ASTData>(name, ASTData(value, Symbol(concatSymbolTree(from), true), Type(double_percision)));
} else if (name == "char") {
newNode = new NodeTree<ASTData>(name, ASTData(value, Symbol(concatSymbolTree(children[0]), true), Type(character))); //Indirection of 1 for array
} else if (name == "string" || name == "triple_quoted_string") {
newNode = new NodeTree<ASTData>(name, ASTData(value, Symbol(concatSymbolTree(children[0]), true), char_string));
newNode = new NodeTree<ASTData>(name, ASTData(value, Symbol(concatSymbolTree(children[0]), true), Type(character, 1))); //Indirection of 1 for array
} else {
return new NodeTree<ASTData>();
}
@@ -153,7 +173,7 @@ std::string ASTTransformation::concatSymbolTree(NodeTree<Symbol>* root) {
concatString += ourValue;
std::vector<NodeTree<Symbol>*> children = root->getChildren();
for (int i = 0; i < children.size(); i++) {
concatString = concatSymbolTree(children[i]);
concatString += concatSymbolTree(children[i]);
}
return concatString;
}

View File

@@ -73,7 +73,7 @@ std::string CGenerator::generate(NodeTree<ASTData>* from) {
case assignment_statement:
return generate(children[0]) + " = " + generate(children[1]);
case declaration_statement:
return ASTData::ValueTypeToString(children[0]->getData().valueType) + " " + generate(children[0]) + " = " + generate(children[1]);
return ValueTypeToCType(children[0]->getData().valueType) + " " + generate(children[0]) + " = " + generate(children[1]);
case if_comp:
if (generate(children[0]) == generatorString)
return generate(children[1]);
@@ -87,6 +87,8 @@ std::string CGenerator::generate(NodeTree<ASTData>* from) {
std::string name = data.symbol.getName();
if (name == "++" || name == "--")
return generate(children[0]) + name;
if (name == "*" && children.size() == 1) //Is dereference, not multiplication
return "*(" + generate(children[0]) + ")";
if (name == "+" || name == "-" || name == "*" || name == "/" || name == "==" || name == ">=" || name == "<=" || name == "!=" || name == "<" || name == ">" || name == "%" || name == "+=" || name == "-=" || name == "*=" || name == "/=") {
return "((" + generate(children[0]) + ")" + name + "(" + generate(children[1]) + "))";
}
@@ -110,25 +112,35 @@ std::string CGenerator::generate(NodeTree<ASTData>* from) {
return output;
}
std::string CGenerator::ValueTypeToCType(ValueType type) {
switch (type) {
std::string CGenerator::ValueTypeToCType(Type type) {
std::string return_type;
switch (type.baseType) {
case none:
return "none";
return_type = "none";
break;
case void_type:
return "void";
return_type = "void";
break;
case boolean:
return "bool";
return_type = "bool";
break;
case integer:
return "int";
return_type = "int";
break;
case floating:
return "float";
case double_percision:
return "double";
return_type = "float";
break;
case double_percision:
return_type = "double";
break;
case character:
return_type = "char";
break;
case char_string:
return "char*";
default:
return "unknown_ValueType";
return_type = "unknown_ValueType";
break;
}
for (int i = 0; i < type.indirection; i++)
return_type += "*";
return return_type;
}

73
src/Type.cpp Normal file
View File

@@ -0,0 +1,73 @@
#include "Type.h"
Type::Type() {
indirection = 0;
baseType = none;
}
Type::Type(ValueType typeIn) {
indirection = 0;
baseType = typeIn;
}
Type::Type(ValueType typeIn, int indirectionIn) {
indirection = indirectionIn;
baseType = typeIn;
}
Type::Type(std::string typeIn) {
indirection = 0;
while (typeIn[typeIn.size() - indirection - 1] == '*') indirection++;
std::string edited = strSlice(typeIn, 0, -(indirection + 1));
if (edited == "void")
baseType = void_type;
else if (edited == "bool")
baseType = boolean;
else if (edited == "int")
baseType = integer;
else if (edited == "float")
baseType = floating;
else if (edited == "double")
baseType = double_percision;
else if (edited == "char")
baseType = character;
else
baseType = none;
std::cout << ":ALKJF:LSKDJF:SDJF:LKSJDF\t\t\t" << typeIn << "\t" << edited << std::endl;
}
Type::~Type() {
}
std::string Type::toString() {
std::string typeString;
switch (baseType) {
case none:
typeString = "none";
break;
case void_type:
typeString = "void";
break;
case boolean:
typeString = "bool";
break;
case integer:
typeString = "int";
break;
case floating:
typeString = "float";
break;
case double_percision:
typeString = "double";
break;
case character:
typeString = "char";
break;
default:
typeString = "unknown_type";
}
for (int i = 0; i < indirection; i++)
typeString += "*";
return typeString;
}