Slight refactoring.

- Factored out CppLanguage::ParseTypeExpression() into one that could
  be used in CLanguageFamily, with some hooks to help differentiate
  what's allowed in C vs C++. Makes the type parsing available for
  C files as well, and consequently allows typecasting to work for
  those.
This commit is contained in:
Rene Gollent 2013-04-19 22:53:10 -04:00
parent 4122ce2aff
commit 87d33c4ff3
6 changed files with 164 additions and 130 deletions

View File

@ -1,4 +1,5 @@
/*
* Copyright 2013, Rene Gollent, rene@gollent.com.
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
@ -22,3 +23,13 @@ CLanguage::Name() const
{
return "C";
}
bool
CLanguage::IsModifierValid(char modifier) const
{
if (modifier == '*')
return true;
return false;
}

View File

@ -15,6 +15,9 @@ public:
virtual ~CLanguage();
virtual const char* Name() const;
protected:
virtual bool IsModifierValid(char modifier) const;
};

View File

@ -1,10 +1,18 @@
/*
* Copyright 2013, Rene Gollent, rene@gollent.com.
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#include "CLanguageFamily.h"
#include <stdlib.h>
#include "TeamTypeInformation.h"
#include "Type.h"
#include "TypeLookupConstraints.h"
CLanguageFamily::CLanguageFamily()
{
@ -22,3 +30,131 @@ CLanguageFamily::GetSyntaxHighlighter() const
// TODO:...
return NULL;
}
status_t
CLanguageFamily::ParseTypeExpression(const BString& expression,
TeamTypeInformation* info, Type*& _resultType) const
{
status_t result = B_OK;
Type* baseType = NULL;
BString parsedName = expression;
BString baseTypeName;
BString arraySpecifier;
parsedName.RemoveAll(" ");
int32 modifierIndex = -1;
modifierIndex = parsedName.FindFirst('*');
if (modifierIndex == -1)
modifierIndex = parsedName.FindFirst('&');
if (modifierIndex == -1)
modifierIndex = parsedName.FindFirst('[');
if (modifierIndex >= 0)
parsedName.MoveInto(baseTypeName, 0, modifierIndex);
else
baseTypeName = parsedName;
modifierIndex = parsedName.FindFirst('[');
if (modifierIndex >= 0) {
parsedName.MoveInto(arraySpecifier, modifierIndex,
parsedName.Length() - modifierIndex);
}
result = info->LookupTypeByName(baseTypeName, TypeLookupConstraints(),
baseType);
if (result != B_OK)
return result;
BReference<Type> typeRef;
typeRef.SetTo(baseType, true);
if (!parsedName.IsEmpty()) {
AddressType* derivedType = NULL;
// walk the list of modifiers trying to add each.
for (int32 i = 0; i < parsedName.Length(); i++) {
if (!IsModifierValid(parsedName[i]))
return B_BAD_VALUE;
address_type_kind typeKind;
switch (parsedName[i]) {
case '*':
{
typeKind = DERIVED_TYPE_POINTER;
break;
}
case '&':
{
typeKind = DERIVED_TYPE_REFERENCE;
break;
}
default:
{
return B_BAD_VALUE;
}
}
if (derivedType == NULL) {
result = baseType->CreateDerivedAddressType(typeKind,
derivedType);
} else {
result = derivedType->CreateDerivedAddressType(typeKind,
derivedType);
}
if (result != B_OK)
return result;
typeRef.SetTo(derivedType, true);
}
_resultType = derivedType;
} else
_resultType = baseType;
if (!arraySpecifier.IsEmpty()) {
ArrayType* arrayType = NULL;
int32 startIndex = 1;
do {
int32 size = strtoul(arraySpecifier.String() + startIndex,
NULL, 10);
if (size < 0)
return B_ERROR;
if (arrayType == NULL) {
result = _resultType->CreateDerivedArrayType(0, size, true,
arrayType);
} else {
result = arrayType->CreateDerivedArrayType(0, size, true,
arrayType);
}
if (result != B_OK)
return result;
typeRef.SetTo(arrayType, true);
startIndex = arraySpecifier.FindFirst('[', startIndex + 1);
} while (startIndex >= 0);
// since a C/C++ array is essentially pointer math,
// the resulting array has to be wrapped in a pointer to
// ensure the element addresses wind up being against the
// correct address.
AddressType* addressType = NULL;
result = arrayType->CreateDerivedAddressType(DERIVED_TYPE_POINTER,
addressType);
if (result != B_OK)
return result;
_resultType = addressType;
}
typeRef.Detach();
return result;
}

View File

@ -15,6 +15,13 @@ public:
virtual ~CLanguageFamily();
virtual SyntaxHighlighter* GetSyntaxHighlighter() const;
virtual status_t ParseTypeExpression(const BString& expression,
TeamTypeInformation* lookup,
Type*& _resultType) const;
protected:
virtual bool IsModifierValid(char modifier) const = 0;
};

View File

@ -7,12 +7,6 @@
#include "CppLanguage.h"
#include <stdlib.h>
#include "TeamTypeInformation.h"
#include "Type.h"
#include "TypeLookupConstraints.h"
CppLanguage::CppLanguage()
{
@ -31,127 +25,11 @@ CppLanguage::Name() const
}
status_t
CppLanguage::ParseTypeExpression(const BString &expression,
TeamTypeInformation* info,
Type*& _resultType) const
bool
CppLanguage::IsModifierValid(char modifier) const
{
status_t result = B_OK;
Type* baseType = NULL;
if (modifier == '*' || modifier == '&')
return true;
BString parsedName = expression;
BString baseTypeName;
BString arraySpecifier;
parsedName.RemoveAll(" ");
int32 modifierIndex = -1;
modifierIndex = parsedName.FindFirst('*');
if (modifierIndex == -1)
modifierIndex = parsedName.FindFirst('&');
if (modifierIndex == -1)
modifierIndex = parsedName.FindFirst('[');
if (modifierIndex >= 0)
parsedName.MoveInto(baseTypeName, 0, modifierIndex);
else
baseTypeName = parsedName;
modifierIndex = parsedName.FindFirst('[');
if (modifierIndex >= 0) {
parsedName.MoveInto(arraySpecifier, modifierIndex,
parsedName.Length() - modifierIndex);
}
result = info->LookupTypeByName(baseTypeName, TypeLookupConstraints(),
baseType);
if (result != B_OK)
return result;
BReference<Type> typeRef;
typeRef.SetTo(baseType, true);
if (!parsedName.IsEmpty()) {
AddressType* derivedType = NULL;
// walk the list of modifiers trying to add each.
for (int32 i = 0; i < parsedName.Length(); i++) {
address_type_kind typeKind;
switch (parsedName[i]) {
case '*':
{
typeKind = DERIVED_TYPE_POINTER;
break;
}
case '&':
{
typeKind = DERIVED_TYPE_REFERENCE;
break;
}
default:
{
return B_BAD_VALUE;
}
}
if (derivedType == NULL) {
result = baseType->CreateDerivedAddressType(typeKind,
derivedType);
} else {
result = derivedType->CreateDerivedAddressType(typeKind,
derivedType);
}
if (result != B_OK)
return result;
typeRef.SetTo(derivedType, true);
}
_resultType = derivedType;
} else
_resultType = baseType;
if (!arraySpecifier.IsEmpty()) {
ArrayType* arrayType = NULL;
int32 startIndex = 1;
do {
int32 size = strtoul(arraySpecifier.String() + startIndex,
NULL, 10);
if (size < 0)
return B_ERROR;
if (arrayType == NULL) {
result = _resultType->CreateDerivedArrayType(0, size, true,
arrayType);
} else {
result = arrayType->CreateDerivedArrayType(0, size, true,
arrayType);
}
if (result != B_OK)
return result;
typeRef.SetTo(arrayType, true);
startIndex = arraySpecifier.FindFirst('[', startIndex + 1);
} while (startIndex >= 0);
// since a C/C++ array is essentially pointer math,
// the resulting array has to be wrapped in a pointer to
// ensure the element addresses wind up being against the
// correct address.
AddressType* addressType = NULL;
result = arrayType->CreateDerivedAddressType(DERIVED_TYPE_POINTER,
addressType);
if (result != B_OK)
return result;
_resultType = addressType;
}
typeRef.Detach();
return result;
return false;
}

View File

@ -16,9 +16,8 @@ public:
virtual const char* Name() const;
virtual status_t ParseTypeExpression(const BString &expression,
TeamTypeInformation* lookup,
Type*& _resultType) const;
protected:
virtual bool IsModifierValid(char modifier) const;
};