Implement support for the "package" keyword.

Refs #6107
This commit is contained in:
Gunnar Beutner 2014-05-03 20:01:23 +02:00 committed by Gunnar Beutner
parent cfa382f0dd
commit b1dab6c074
9 changed files with 76 additions and 6 deletions

View File

@ -20,6 +20,7 @@ abstract class DynamicObject
}}}
};
[config, get_protected] String type (TypeName);
[config] String package;
[config, get_protected] Array::Ptr templates;
[config] Dictionary::Ptr methods;
[config] Dictionary::Ptr vars (VarsRaw);

View File

@ -523,6 +523,7 @@ Value AExpression::OpObject(const AExpression* expr, const Dictionary::Ptr& loca
String type = left->Get(1);
AExpression::Ptr aname = left->Get(2);
AExpression::Ptr filter = left->Get(3);
String package = left->Get(4);
String name = aname->Evaluate(locals);
@ -560,6 +561,7 @@ Value AExpression::OpObject(const AExpression* expr, const Dictionary::Ptr& loca
item->AddExpression(exprl);
item->SetAbstract(abstract);
item->SetScope(locals);
item->SetPackage(package);
item->Compile()->Register();
ObjectRule::AddRule(type, name, exprl, filter, expr->m_DebugInfo, locals);

View File

@ -24,6 +24,8 @@
%require "type",
%attribute %string "type",
%attribute %string "package",
%attribute %array "templates" {
%attribute %string "*"
},

View File

@ -231,6 +231,7 @@ ignore return T_IGNORE;
function return T_FUNCTION;
lambda return T_LAMBDA;
return return T_RETURN;
package return T_PACKAGE;
\<\< { yylval->op = &AExpression::OpShiftLeft; return T_SHIFT_LEFT; }
\>\> { yylval->op = &AExpression::OpShiftRight; return T_SHIFT_RIGHT; }
\<= { yylval->op = &AExpression::OpLessThanOrEqual; return T_LESS_THAN_OR_EQUAL; }

View File

@ -160,6 +160,7 @@ static void MakeRBinaryOp(Value** result, AExpression::OpCallback& op, Value *le
%token T_FUNCTION "function (T_FUNCTION)"
%token T_LAMBDA "lambda (T_LAMBDA)"
%token T_RETURN "return (T_RETURN)"
%token T_PACKAGE "package (T_PACKAGE)"
%type <text> identifier
%type <array> rterm_items
@ -213,6 +214,8 @@ static std::stack<TypeRuleList::Ptr> m_RuleLists;
static ConfigType::Ptr m_Type;
static Dictionary::Ptr m_ModuleScope;
static String m_Package;
static int m_StatementNum;
static bool m_Apply;
static bool m_ObjectAssign;
@ -224,6 +227,10 @@ void ConfigCompiler::Compile(void)
{
m_ModuleScope = make_shared<Dictionary>();
String parentPackage = m_Package;
int parentStatementNum = m_StatementNum;
m_StatementNum = 0;
try {
yyparse(this);
} catch (const ConfigError& ex) {
@ -232,6 +239,9 @@ void ConfigCompiler::Compile(void)
} catch (const std::exception& ex) {
ConfigCompilerContext::GetInstance()->AddMessage(true, DiagnosticInformation(ex));
}
m_Package = parentPackage;
m_StatementNum = parentStatementNum;
}
#define scanner (context->GetScanner())
@ -243,13 +253,54 @@ statements: /* empty */
| statements statement
;
statement: type | include | include_recursive | library | constant | newlines
statement: type | package | include | include_recursive | library | constant
{
m_StatementNum++;
}
| newlines
{ }
| lterm
{
AExpression::Ptr aexpr = *$1;
aexpr->Evaluate(m_ModuleScope);
delete $1;
m_StatementNum++;
}
;
package: T_PACKAGE rterm sep
{
AExpression::Ptr aexpr = *$2;
delete $2;
if (!m_Package.IsEmpty())
BOOST_THROW_EXCEPTION(std::invalid_argument("Package name cannot be changed once it's been set."));
if (m_StatementNum != 0)
BOOST_THROW_EXCEPTION(std::invalid_argument("'package' directive must be the first statement in a file."));
m_Package = aexpr->Evaluate(m_ModuleScope);
}
| T_PACKAGE rterm rterm_scope sep
{
AExpression::Ptr aexpr = *$2;
delete $2;
AExpression::Ptr ascope = *$3;
delete $3;
if (!m_Package.IsEmpty())
BOOST_THROW_EXCEPTION(std::invalid_argument("Package name cannot be changed once it's been set."));
m_Package = aexpr->Evaluate(m_ModuleScope);
try {
ascope->Evaluate(m_ModuleScope);
m_Package = String();
} catch (...) {
m_Package = String();
}
}
;
@ -433,7 +484,7 @@ object:
m_Assign = make_shared<AExpression>(&AExpression::OpLiteral, false, DebugInfo());
m_Ignore = make_shared<AExpression>(&AExpression::OpLiteral, false, DebugInfo());
}
object_declaration identifier rterm rterm_scope sep
object_declaration identifier rterm rterm_scope
{
m_ObjectAssign = false;
@ -460,6 +511,8 @@ object:
args->Add(filter);
args->Add(m_Package);
$$ = new Value(make_shared<AExpression>(&AExpression::OpObject, args, exprl, DebugInfoRange(@2, @5)));
m_Assign.reset();

View File

@ -49,10 +49,11 @@ ConfigItem::ItemMap ConfigItem::m_Items;
*/
ConfigItem::ConfigItem(const String& type, const String& name,
bool abstract, const AExpression::Ptr& exprl,
const DebugInfo& debuginfo, const Dictionary::Ptr& scope)
const DebugInfo& debuginfo, const Dictionary::Ptr& scope,
const String& package)
: m_Type(type), m_Name(name), m_Abstract(abstract), m_Validated(false),
m_ExpressionList(exprl), m_DebugInfo(debuginfo),
m_Scope(scope)
m_Scope(scope), m_Package(package)
{
}

View File

@ -39,7 +39,7 @@ public:
ConfigItem(const String& type, const String& name, bool abstract,
const AExpression::Ptr& exprl, const DebugInfo& debuginfo,
const Dictionary::Ptr& scope);
const Dictionary::Ptr& scope, const String& package);
String GetType(void) const;
String GetName(void) const;
@ -57,6 +57,8 @@ public:
Dictionary::Ptr GetScope(void) const;
String GetPackage(void) const;
static ConfigItem::Ptr GetObject(const String& type,
const String& name);
static bool HasObject(const String& type, const String& name);
@ -79,6 +81,7 @@ private:
items. */
DebugInfo m_DebugInfo; /**< Debug information. */
Dictionary::Ptr m_Scope; /**< variable scope. */
String m_Package; /**< The package. */
DynamicObject::Ptr m_Object;

View File

@ -60,6 +60,11 @@ void ConfigItemBuilder::SetScope(const Dictionary::Ptr& scope)
m_Scope = scope;
}
void ConfigItemBuilder::SetPackage(const String& package)
{
m_Package = package;
}
void ConfigItemBuilder::AddExpression(const AExpression::Ptr& expr)
{
m_Expressions->Add(expr);
@ -99,5 +104,5 @@ ConfigItem::Ptr ConfigItemBuilder::Compile(void)
AExpression::Ptr exprl = make_shared<AExpression>(&AExpression::OpDict, exprs, true, m_DebugInfo);
return make_shared<ConfigItem>(m_Type, m_Name, m_Abstract, exprl,
m_DebugInfo, m_Scope);
m_DebugInfo, m_Scope, m_Package);
}

View File

@ -46,6 +46,7 @@ public:
void SetName(const String& name);
void SetAbstract(bool abstract);
void SetScope(const Dictionary::Ptr& scope);
void SetPackage(const String& name);
void AddExpression(const AExpression::Ptr& expr);
@ -58,6 +59,7 @@ private:
Array::Ptr m_Expressions; /**< Expressions for this item. */
DebugInfo m_DebugInfo; /**< Debug information. */
Dictionary::Ptr m_Scope; /**< variable scope. */
String m_Package; /**< The package. */
};
}