Commit be7ed24d authored by ussrhero's avatar ussrhero
Browse files

Expreval/consttype

parent ba832699
This diff is collapsed.
#pragma once
#include "exprparser.h"
#include <kdlib/typeinfo.h>
namespace kdlib {
bool isBaseTypeKeyWord(const clang::Token& token);
bool isStandardIntType(const clang::Token& token);
bool isInt64KeyWord(const clang::Token& token);
namespace parser {
class BaseTypeMatcher : public Matcher
{
public:
MatchResult match(const TokenRange& matchRange);
std::string getTypeName() const;
TypeInfoPtr getBaseType() const;
private:
bool m_const;
TypeInfoPtr m_typeInfo;
std::string m_typeName;
};
}
}
\ No newline at end of file
......@@ -34,8 +34,6 @@ kdlib::TypeInfoPtr getStandardIntType(const std::string& name);
bool isBinOperation(const clang::Token& token);
bool isInt64KeyWord(const clang::Token& token);
///////////////////////////////////////////////////////////////////////////////
TypedValue evalExpr(const std::wstring& expr, const ScopePtr& scope, const TypeInfoProviderPtr& typeInfoProvider)
......@@ -849,14 +847,35 @@ std::string getTypeModifierRecursive(const parser::ComplexMatcher& matcher)
if (matcher.isPointer())
{
bool needSpace = false;
for (auto p : matcher.getPointerMatcher().getPointerMatchers())
{
if (needSpace)
{
sstr << ' ';
needSpace = false;
}
sstr << '*';
if (p.isConst())
{
sstr << "const";
needSpace = true;
}
}
}
if (matcher.isReference())
{
if (matcher.getRefMatcher().isLvalue())
sstr << '&';
else
sstr << "&&";
}
if (matcher.isNestedMatcher())
{
sstr << '(' << getTypeModifierRecursive(matcher.getNestedMatcher().getInnerMatcher()) << ')';
}
}
if (matcher.isArray())
{
......@@ -884,15 +903,10 @@ TypeInfoPtr TypeEval::getResult()
{
using namespace parser;
std::list<clang::Token> tokens;
std::copy_if(m_tokens->cbegin(), m_tokens->cend(), std::back_inserter(tokens), [](auto& token){
return !token.is(clang::tok::kw_const);
});
TypeMatcher typeMatcher;
QualifiedTypeMatcher typeMatcher;
auto matcher = all_of(typeMatcher, token_is(m_endToken));
auto matchResult = matcher.match(std::make_pair(tokens.cbegin(), tokens.cend()));
auto matchResult = matcher.match(std::make_pair(m_tokens->cbegin(), m_tokens->cend()));
if (!matchResult.isMatched())
throw ExprException(L"error syntax");
......@@ -901,11 +915,11 @@ TypeInfoPtr TypeEval::getResult()
if (typeMatcher.isBasedType())
{
typeInfo = getBaseType();
typeInfo = typeMatcher.getBaseTypeMatcher().getBaseType();
}
else if (typeMatcher.isStandardIntType())
{
typeInfo = getStandardIntType();
typeInfo = getStandardIntType(typeMatcher.getStandardIntMatcher());
}
else if (typeMatcher.isCustomType())
{
......@@ -924,8 +938,7 @@ TypeInfoPtr TypeEval::getResult()
typeInfo = applyComplexModifierRecursive(typeMatcher.getComplexMather(), typeInfo);
}
tokens.erase(matchResult.begin(), matchResult.end());
*m_tokens = tokens;
m_tokens->erase(matchResult.begin(), matchResult.end());
return typeInfo;
}
......@@ -936,15 +949,10 @@ std::list<std::string> TypeEval::getTemplateArgList()
{
using namespace parser;
std::list<clang::Token> tokens;
std::copy_if(m_tokens->cbegin(), m_tokens->cend(), std::back_inserter(tokens), [](auto& token) {
return !token.is(clang::tok::kw_const);
});
TypeMatcher typeMatcher;
auto matcher = all_of(typeMatcher, token_is(m_endToken));
auto matchResult = matcher.match(std::make_pair(tokens.cbegin(), tokens.cend()));
auto matchResult = matcher.match(std::make_pair(m_tokens->cbegin(), m_tokens->cend()));
if (!matchResult.isMatched())
throw ExprException(L"error syntax");
......@@ -956,59 +964,33 @@ std::list<std::string> TypeEval::getTemplateArgList()
if (customMatcher.isTemplate())
{
const auto& argList = customMatcher.getTemplateMatcher().getTemplateArgs();
std::list<std::string> argStrList;
const auto& argListMatcher = customMatcher.getTemplateMatcher().getTemplateArgs();
for (auto& arg : argList)
{
if (arg.isType())
{
argStrList.push_back(getTypeName(arg.getTypeMatcher()));
}
else if (arg.isExpression())
{
auto value = ExprEval2(m_scope, m_typeInfoProvider, arg.getExpressionMatcher().getMatchResult().getMatchedRange()).getResult();
argStrList.push_back(std::to_string(value.getValue().asLongLong()));
}
else
{
throw ExprException(L"error syntax");
}
}
return argStrList;
return getTemplateArgList(argListMatcher);
}
if (customMatcher.isNestedTemplate())
{
const auto& templateMatcher = customMatcher.getNestedTemplateMatcher();
const auto& argList = templateMatcher.getTemplateArgs1();
const auto& argListMatcher = templateMatcher.getTemplateArgs1();
std::list<std::string> argStrList;
for (auto& arg : argList)
{
if (arg.isType())
{
argStrList.push_back(getTypeName(arg.getTypeMatcher()));
}
else if (arg.isExpression())
{
auto value = ExprEval2(m_scope, m_typeInfoProvider, arg.getExpressionMatcher().getMatchResult().getMatchedRange()).getResult();
argStrList.push_back(std::to_string(value.getValue().asLongLong()));
}
else
{
throw ExprException(L"error syntax");
}
}
std::list<std::string> argStrList = getTemplateArgList(argListMatcher);
std::string templateName = templateMatcher.getNestedTemplateName();
templateName += '<';
templateName += getTemplateArgs(templateMatcher.getTemplateArgs2());
const auto& nestedArgList = getTemplateArgList(templateMatcher.getTemplateArgs2());
std::string argsStr;
for (const auto& arg : nestedArgList)
{
if (!argsStr.empty())
argsStr += ',';
argsStr += arg;
}
templateName += argsStr;
templateName += '>';
......@@ -1022,23 +1004,20 @@ std::list<std::string> TypeEval::getTemplateArgList()
///////////////////////////////////////////////////////////////////////////////
std::string TypeEval::getTemplateArgs(const parser::ListMatcher<parser::TemplateArgMatcher>& argList)
std::list<std::string> TypeEval::getTemplateArgList(const parser::ListMatcher<parser::TemplateArgMatcher>& argList)
{
std::string argsStr;
std::list<std::string> argStrList;
for (auto& arg : argList)
{
if (!argsStr.empty())
argsStr += ',';
if (arg.isType())
{
argsStr += getTypeName(arg.getTypeMatcher());
argStrList.push_back(getTypeName(arg.getTypeMatcher()));
}
else if (arg.isExpression())
{
auto value = ExprEval2(m_scope, m_typeInfoProvider, arg.getExpressionMatcher().getMatchResult().getMatchedRange()).getResult();
argsStr += std::to_string(value.getValue().asLongLong());
argStrList.push_back(std::to_string(value.getValue().asLongLong()));
}
else
{
......@@ -1046,6 +1025,23 @@ std::string TypeEval::getTemplateArgs(const parser::ListMatcher<parser::Template
}
}
return argStrList;
}
///////////////////////////////////////////////////////////////////////////////
std::string TypeEval::getTemplateArgs(const parser::ListMatcher<parser::TemplateArgMatcher>& argListMatcher)
{
const auto& argList = getTemplateArgList(argListMatcher);
std::string argsStr;
for (const auto& arg : argList)
{
if (!argsStr.empty())
argsStr += ',';
argsStr += arg;
}
return argsStr;
}
......@@ -1054,7 +1050,7 @@ std::string TypeEval::getTemplateArgs(const parser::ListMatcher<parser::Template
std::string TypeEval::getTemplateName(const parser::TemplateMatcher& templateMatcher)
{
std::string templateName = getTemplateArgs(templateMatcher.getTemplateArgs());
templateName.insert(templateName.begin(), '<');
if (templateName.back() == '>')
templateName.insert(templateName.end(), ' ');
......@@ -1158,18 +1154,27 @@ TypeInfoPtr TypeEval::getCustomType(const parser::CustomTypeMatcher& customMatc
///////////////////////////////////////////////////////////////////////////////
std::string TypeEval::getTypeName(const parser::TypeMatcher& typeMatcher)
std::string TypeEval::getTypeName(const parser::QualifiedTypeMatcher& typeMatcher)
{
std::string typeName;
if (typeMatcher.isConst())
{
typeName = "const ";
}
if (typeMatcher.isBasedType())
{
typeName = getBaseTypeName(typeMatcher.getBaseTypeMatcher());
typeName += typeMatcher.getBaseTypeMatcher().getTypeName();
}
else
if (typeMatcher.isCustomType())
{
typeName = getCustomTypeName(typeMatcher.getCustomMatcher());
typeName += getCustomTypeName(typeMatcher.getCustomMatcher());
}
else
{
throw ExprException(L"error syntax");
}
if (typeMatcher.isComplexType())
......@@ -1224,182 +1229,10 @@ std::string TypeEval::getCustomTypeName(const parser::CustomTypeMatcher& customM
///////////////////////////////////////////////////////////////////////////////
std::string TypeEval::getBaseTypeName(const parser::BaseTypeMatcher& baseTypeMatcher)
{
if (baseTypeMatcher.getMatchResult().begin()->is(clang::tok::kw_void))
{
return "void";
}
std::unique_ptr<BaseTypeBuilder> baseTypeBuilder(new EmptyBaseTypeBuilder);
for (auto& token : baseTypeMatcher.getMatchResult())
{
if (token.is(clang::tok::kw_int))
{
baseTypeBuilder.reset(baseTypeBuilder->addInt());
}
else
if (token.is(clang::tok::kw_char))
{
baseTypeBuilder.reset(baseTypeBuilder->addChar());
}
else
if (token.is(clang::tok::kw_short))
{
baseTypeBuilder.reset(baseTypeBuilder->addShort());
}
else
if (token.is(clang::tok::kw_unsigned))
{
baseTypeBuilder.reset(baseTypeBuilder->addUnsigned());
}
else
if (token.is(clang::tok::kw_signed))
{
baseTypeBuilder.reset(baseTypeBuilder->addSigned());
}
else
if (token.is(clang::tok::kw_long))
{
baseTypeBuilder.reset(baseTypeBuilder->addLong());
}
else
if (isInt64KeyWord(token))
{
baseTypeBuilder.reset(baseTypeBuilder->addLong());
baseTypeBuilder.reset(baseTypeBuilder->addLong());
}
else
if (token.is(clang::tok::kw_float))
{
baseTypeBuilder.reset(baseTypeBuilder->addFloat());
}
else
if (token.is(clang::tok::kw_double))
{
baseTypeBuilder.reset(baseTypeBuilder->addDouble());
}
else
{
throw ExprException(L"error syntax");
}
}
return baseTypeBuilder->getTypeName();
}
///////////////////////////////////////////////////////////////////////////////
TypeInfoPtr TypeEval::getBaseType()
TypeInfoPtr TypeEval::getStandardIntType(const parser::StandardIntMatcher& stdIntMatcher)
{
if (m_tokens->front().is(clang::tok::kw_void))
{
m_tokens->pop_front();
return loadType(L"Void");
}
std::unique_ptr<BaseTypeBuilder> baseTypeBuilder(new EmptyBaseTypeBuilder);
while (true)
{
auto token = m_tokens->front();
if (token.is(m_endToken))
break;
if (token.is(clang::tok::kw_int))
{
baseTypeBuilder.reset(baseTypeBuilder->addInt());
m_tokens->pop_front();
continue;
}
if (token.is(clang::tok::kw_char))
{
baseTypeBuilder.reset(baseTypeBuilder->addChar());
m_tokens->pop_front();
continue;
}
if (token.is(clang::tok::kw_short))
{
baseTypeBuilder.reset(baseTypeBuilder->addShort());
m_tokens->pop_front();
continue;
}
if (token.is(clang::tok::kw_unsigned))
{
baseTypeBuilder.reset(baseTypeBuilder->addUnsigned());
m_tokens->pop_front();
continue;
}
if (token.is(clang::tok::kw_signed))
{
baseTypeBuilder.reset(baseTypeBuilder->addSigned());
m_tokens->pop_front();
continue;
}
if (token.is(clang::tok::kw_long))
{
baseTypeBuilder.reset(baseTypeBuilder->addLong());
m_tokens->pop_front();
continue;
}
if (isInt64KeyWord(token))
{
baseTypeBuilder.reset(baseTypeBuilder->addLong());
baseTypeBuilder.reset(baseTypeBuilder->addLong());
m_tokens->pop_front();
continue;
}
if (token.is(clang::tok::kw_float))
{
baseTypeBuilder.reset(baseTypeBuilder->addFloat());
m_tokens->pop_front();
continue;
}
if (token.is(clang::tok::kw_double))
{
baseTypeBuilder.reset(baseTypeBuilder->addDouble());
m_tokens->pop_front();
continue;
}
if (token.is(clang::tok::kw_const))
{
m_tokens->pop_front();
continue;
}
if (token.isOneOf(clang::tok::star, clang::tok::l_paren, clang::tok::l_square,
clang::tok::amp, clang::tok::ampamp))
break;
throw ExprException(L"error syntax");
}
return baseTypeBuilder->getResult();
}
///////////////////////////////////////////////////////////////////////////////
TypeInfoPtr TypeEval::getStandardIntType()
{
auto token = m_tokens->front();
m_tokens->pop_front();
assert(token.is(clang::tok::identifier));
std::string name(token.getIdentifierInfo()->getNameStart(), token.getLength());
auto& token = stdIntMatcher.getMatchResult().begin();
std::string name(token->getIdentifierInfo()->getNameStart(), token->getLength());
return kdlib::getStandardIntType(name);
}
......
......@@ -519,20 +519,19 @@ public:
private:
TypeInfoPtr getBaseType();
TypeInfoPtr getStandardIntType();
TypeInfoPtr getStandardIntType(const parser::StandardIntMatcher& stdIntMatcher);
std::string getTemplateArgs(const parser::ListMatcher<parser::TemplateArgMatcher>& argList);
std::list<std::string> getTemplateArgList(const parser::ListMatcher<parser::TemplateArgMatcher>& argList);
std::string getTemplateName(const parser::TemplateMatcher& templateMatcher);
std::string getNestedTemplateName(const parser::DoubleTemplateMatcher& templateMatcher);
std::string getTypeName(const parser::TypeMatcher& typeMatcher);
std::string getTypeName(const parser::QualifiedTypeMatcher& typeMatcher);
std::string getBaseTypeName(const parser::BaseTypeMatcher& baseTypeMatcher);
//std::string getBaseTypeName(const parser::BaseTypeMatcher& baseTypeMatcher);
std::string getCustomTypeName(const parser::CustomTypeMatcher& customMatcher);
......@@ -550,811 +549,6 @@ private:
///////////////////////////////////////////////////////////////////////////////
class BaseTypeBuilder {
public:
virtual TypeInfoPtr getResult() = 0;
virtual std::string getTypeName() = 0;
virtual BaseTypeBuilder* addChar() = 0;
virtual BaseTypeBuilder* addShort() = 0;
virtual BaseTypeBuilder* addInt() = 0;
virtual BaseTypeBuilder* addUnsigned() = 0;
virtual BaseTypeBuilder* addSigned() = 0;
virtual BaseTypeBuilder* addLong() = 0;
virtual BaseTypeBuilder* addFloat() = 0;
virtual BaseTypeBuilder* addDouble() = 0;
};
class DeclBaseTypeBuilder : public BaseTypeBuilder
{
BaseTypeBuilder* addChar() override {
throw ExprException(L"bad syntax");
}
BaseTypeBuilder* addShort() override {
throw ExprException(L"bad syntax");
}
BaseTypeBuilder* addInt() override {
throw ExprException(L"bad syntax");
}
BaseTypeBuilder* addFloat() {
throw ExprException(L"bad syntax");
}
BaseTypeBuilder* addDouble() {
throw ExprException(L"bad syntax");
}
};
class UnsignedCharBaseTypeBuilder : public DeclBaseTypeBuilder
{
TypeInfoPtr getResult() override {
return loadType(L"UInt1B");
}
std::string getTypeName() override
{
return "unsigned char";
}
BaseTypeBuilder* addUnsigned() override {
return this;
}
BaseTypeBuilder* addSigned() override {
throw ExprException(L"bad syntax");
}
BaseTypeBuilder* addLong() override {
throw ExprException(L"bad syntax");
}
};
class SignedCharBaseTypeBuilder : public DeclBaseTypeBuilder
{
TypeInfoPtr getResult() override {
return loadType(L"Int1B");
}
std::string getTypeName() override
{
return "char";
}
BaseTypeBuilder* addUnsigned() override {
throw ExprException(L"bad syntax");
}
BaseTypeBuilder* addSigned() override {
return this;
}
BaseTypeBuilder* addLong() override {
throw ExprException(L"bad syntax");
}
};