MultiDeclaratorStatement
using CLanguage.Compiler;
using CLanguage.Interpreter;
using CLanguage.Types;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
namespace CLanguage.Syntax
{
[System.Runtime.CompilerServices.NullableContext(1)]
[System.Runtime.CompilerServices.Nullable(0)]
public class MultiDeclaratorStatement : Statement
{
public DeclarationSpecifiers Specifiers;
[System.Runtime.CompilerServices.Nullable(new byte[] {
2,
1
})]
public List<InitDeclarator> InitDeclarators;
public override bool AlwaysReturns => false;
public MultiDeclaratorStatement(DeclarationSpecifiers specifiers, [System.Runtime.CompilerServices.Nullable(new byte[] {
2,
1
})] List<InitDeclarator> initDeclarators)
{
Specifiers = specifiers;
InitDeclarators = initDeclarators;
}
public override string ToString()
{
return string.Join(" ", Specifiers.TypeSpecifiers) + ((InitDeclarators != null) ? (" " + string.Join(", ", InitDeclarators)) : "");
}
protected override void DoEmit(EmitContext ec)
{
if (InitDeclarators != null) {
foreach (InitDeclarator initDeclarator in InitDeclarators) {
if ((Specifiers.StorageClassSpecifier & StorageClassSpecifier.Typedef) == StorageClassSpecifier.None) {
CType cType = ec.MakeCType(Specifiers, initDeclarator.Declarator, initDeclarator.Initializer, null);
string declaredIdentifier = initDeclarator.Declarator.DeclaredIdentifier;
CFunctionType cFunctionType = cType as CFunctionType;
if (cFunctionType != null && !HasStronglyBoundPointer(initDeclarator.Declarator)) {
CStructType cStructType = cFunctionType.ReturnType as CStructType;
if (cStructType != null && initDeclarator.Initializer == null) {
FunctionDeclarator functionDeclarator = initDeclarator.Declarator as FunctionDeclarator;
if (functionDeclarator != null && functionDeclarator.CouldBeCtorCall)
GetCtorInitializerStatement(declaredIdentifier, cStructType, functionDeclarator).Emit(ec);
}
} else if (initDeclarator.Initializer != null) {
VariableExpression left = new VariableExpression(declaredIdentifier, Location.Null, Location.Null);
Expression initializerExpression = GetInitializerExpression(initDeclarator.Initializer);
new ExpressionStatement(new AssignExpression(left, initializerExpression)).Emit(ec);
}
}
}
}
}
public override void AddDeclarationToBlock(BlockContext context)
{
Block block = context.Block;
if (InitDeclarators != null) {
foreach (InitDeclarator initDeclarator in InitDeclarators) {
if ((Specifiers.StorageClassSpecifier & StorageClassSpecifier.Typedef) != 0) {
string declaredIdentifier = initDeclarator.Declarator.DeclaredIdentifier;
CType value = context.MakeCType(Specifiers, initDeclarator.Declarator, initDeclarator.Initializer, block);
block.Typedefs[declaredIdentifier] = value;
continue;
}
CType cType = context.MakeCType(Specifiers, initDeclarator.Declarator, initDeclarator.Initializer, block);
string declaredIdentifier2 = initDeclarator.Declarator.DeclaredIdentifier;
CFunctionType cFunctionType = cType as CFunctionType;
if (cFunctionType != null && !HasStronglyBoundPointer(initDeclarator.Declarator)) {
CStructType cStructType = cFunctionType.ReturnType as CStructType;
if (cStructType != null && initDeclarator.Initializer == null) {
FunctionDeclarator functionDeclarator = initDeclarator.Declarator as FunctionDeclarator;
if (functionDeclarator != null && functionDeclarator.CouldBeCtorCall) {
block.AddVariable(declaredIdentifier2, cStructType);
ExpressionStatement ctorInitializerStatement = GetCtorInitializerStatement(declaredIdentifier2, cStructType, functionDeclarator);
block.InitStatements.Add(ctorInitializerStatement);
goto IL_026a;
}
}
IdentifierDeclarator identifierDeclarator = initDeclarator.Declarator.InnerDeclarator as IdentifierDeclarator;
string nameContext = (identifierDeclarator != null && identifierDeclarator.Context.Count > 0) ? string.Join("::", identifierDeclarator.Context) : "";
CompiledFunction item = new CompiledFunction(declaredIdentifier2, nameContext, cFunctionType, null);
block.Functions.Add(item);
} else {
CArrayType cArrayType = cType as CArrayType;
if (cArrayType != null && !cArrayType.Length.HasValue && initDeclarator.Initializer != null) {
StructuredInitializer structuredInitializer = initDeclarator.Initializer as StructuredInitializer;
if (structuredInitializer != null) {
int num = 0;
foreach (Initializer initializer in structuredInitializer.Initializers) {
if (initializer.Designation == null)
num++;
else {
foreach (InitializerDesignator designator in initializer.Designation.Designators) {
InitializerDesignator initializerDesignator = designator;
num++;
}
}
}
cArrayType = new CArrayType(cArrayType.ElementType, num);
}
}
block.AddVariable(declaredIdentifier2, cType ?? CBasicType.SignedInt);
}
goto IL_026a;
IL_026a:
if (initDeclarator.Initializer != null) {
VariableExpression left = new VariableExpression(declaredIdentifier2, Location.Null, Location.Null);
Expression initializerExpression = GetInitializerExpression(initDeclarator.Initializer);
block.InitStatements.Add(new ExpressionStatement(new AssignExpression(left, initializerExpression)));
}
}
} else {
CType cType2 = context.MakeCType(Specifiers, null, block);
CStructType cStructType2 = cType2 as CStructType;
if (cStructType2 != null) {
string name = cStructType2.Name;
if (!string.IsNullOrEmpty(name))
block.Structures[name] = cStructType2;
} else {
CEnumType cEnumType = cType2 as CEnumType;
if (cEnumType != null) {
string text = cEnumType.Name;
if (string.IsNullOrEmpty(text))
text = "e" + cEnumType.GetHashCode().ToString();
block.Enums[text] = cEnumType;
}
}
}
}
private static ExpressionStatement GetCtorInitializerStatement(string name, CStructType ctorDeclType, FunctionDeclarator ctorDecl)
{
VariableExpression variableExpression = new VariableExpression(name, Location.Null, Location.Null);
new AddressOfExpression(variableExpression);
MemberFromReferenceExpression fun = new MemberFromReferenceExpression(variableExpression, ctorDeclType.Name);
IEnumerable<Expression> args = from p in ctorDecl.Parameters
select p.CtorArgumentValue;
return new ExpressionStatement(new FuncallExpression(fun, args));
}
private static Expression GetInitializerExpression(Initializer init)
{
if (init is ExpressionInitializer)
return ((ExpressionInitializer)init).Expression;
if (init is StructuredInitializer) {
StructuredInitializer obj = (StructuredInitializer)init;
StructureExpression structureExpression = new StructureExpression();
{
foreach (Initializer initializer in obj.Initializers) {
Expression initializerExpression = GetInitializerExpression(initializer);
if (initializer.Designation == null || initializer.Designation.Designators.Count == 0) {
StructureExpression.Item item = new StructureExpression.Item(null, GetInitializerExpression(initializer));
structureExpression.Items.Add(item);
} else {
foreach (InitializerDesignator designator in initializer.Designation.Designators) {
StructureExpression.Item item2 = new StructureExpression.Item(designator.ToString(), initializerExpression);
structureExpression.Items.Add(item2);
}
}
}
return structureExpression;
}
}
throw new NotSupportedException(init.ToString());
}
[System.Runtime.CompilerServices.NullableContext(2)]
private static bool HasStronglyBoundPointer(Declarator d)
{
if (d == null)
return false;
if (d is PointerDeclarator && ((PointerDeclarator)d).StrongBinding)
return true;
return HasStronglyBoundPointer(d.InnerDeclarator);
}
}
}