private void CheckExpressionNode(BfsExpression exp, BfsExpGroup group, IBfsDataBlock block)
{
for (int index = 0; index < group.Members.Count; index++)
{
IBfsExpNode node = group.Members[index];
if (node is BfsOperator)
continue;
if (node is BfsExpGroup)
CheckExpressionNode(exp, node as BfsExpGroup, block);
else if (node is BfsCallExp)
{
BfsCallExp call = node as BfsCallExp;
if (call.FunctionName != "sizeof")
{
BfsCompiler.ReportError(call.NameSourceRange,
"Unknown function: '" + call.FunctionName + "'");
break;
}
//If the argument in sizeof(data-block) can be found.
else if (schema.DataBlocks.ContainsKey(call.FunctionArgument))
{
if (schema.DataBlocks[call.FunctionArgument] is IBfsStructType)
CalculateStructSize(call.SourceRange, schema.DataBlocks[call.FunctionArgument] as IBfsStructType);
call.SizeInBytes = schema.DataBlocks[call.FunctionArgument].SizeInBytes;
continue;
}
else
BfsCompiler.ReportError(call.ArgumentSourceRange,
"Could not find the data-block: '"+call.FunctionArgument+"'");
}
else if (node is BfsUnresolvedVariableExp)
{
BfsUnresolvedVariableExp unresolved = node as BfsUnresolvedVariableExp;
//Boolean(true/false)?
if (unresolved.ToString() == "true" || unresolved.ToString() == "false")
{
BfsBooleanExp booleanExp = new BfsBooleanExp();
booleanExp.SourceRange = unresolved.SourceRange;
booleanExp.Value = (unresolved.ToString() == "true") ? true : false;
group.Members.Insert(index, booleanExp);
group.Members.Remove(unresolved);
continue;
}
//Value expression?
if (unresolved.ToString() == "value")
{
if (block is IBfsConsumptionType)
{
BfsValueExp valueExp = new BfsValueExp();
valueExp.SourceRange = unresolved.SourceRange;
group.Members.Insert(index, valueExp);
group.Members.Remove(unresolved);
continue;
}
else
{
BfsCompiler.ReportError(unresolved.SourceRange,
"The 'value' expression variable may only be used in consumed types.");
continue;
}
}
//Else it is a named variable.
BfsExpressionVariable namedVar = new BfsExpressionVariable();
namedVar.SourceRange = node.SourceRange;
group.Members.Insert(index, namedVar);
group.Members.Remove(node);
string containertype = block.ToString();
//Check hiearchy
IBfsDataBlock container = block;
for (int i = 0; i < unresolved.NameHierarchy.Count; i++)
{
string varname = unresolved.NameHierarchy[i];
if (container == null)
{
BfsCompiler.ReportError(node.SourceRange,
"Variable '" + unresolved.NameHierarchy[i - 1] + "' cannot contain any variables because it of type: " + containertype);
break;
}
if (container.LocalFields.ContainsKey(varname))
{
namedVar.NameHierarchy.Add(container.LocalFields[varname]);
containertype = " local variable";
container = null;
}
else if (container is IBfsStructType && (container as IBfsStructType).StructFields.ContainsKey(varname))
{
IBfsType type = (container as IBfsStructType).StructFields[varname].FieldType;
IBfsNamedField namedtype = (container as IBfsStructType).StructFields[varname];
if (type is BfsNamedType)
{
container = (type as BfsNamedType).DataBlock;
if (container is IBfsConsumptionType)
{
IBfsConsumptionType consumed = container as IBfsConsumptionType;
namedtype.PrimitiveType = consumed.PrimitiveType;
}
namedVar.NameHierarchy.Add(namedtype);
}
else if (type is BfsPrimitiveType)
{
containertype = "primitive type";
namedVar.NameHierarchy.Add(namedtype);
container = null;
}
else if (type is BfsFunctionType)
{
containertype = "function type";
namedVar.NameHierarchy.Add(namedtype);
container = null;
}
else BfsCompiler.ReportError(container.SourceRange, "Unexpected error. Unknown type.");
}
else
{
containertype = "unknown variable or enum-alias.";
BfsExpressionUnknown unknown = new BfsExpressionUnknown();
unknown.Name = varname;
unknown.SourceRange = unresolved.SourceRange;
namedVar.NameHierarchy.Add(unknown);
container = null;
}
}
//Building map over dependant variables.
exp.DependantVariables.Add(namedVar);
}
}
}