The StaDyn Programming Language
Source code documentation of StaDyn, a hybrid static and dynamic typing language.
CGUnaryOperation.cs
Go to the documentation of this file.
1 using System;
2 using CodeGeneration.Operations;
3 using TypeSystem.Operations;
4 using TypeSystem;
5 using ErrorManagement;
6 using AST;
7 using Tools;
8 using System.Collections.Generic;
9 using CodeGeneration.ExceptionManagement;
10 namespace CodeGeneration.NewOperations
11 {
12 
13  internal class CGUnaryOperation<T> : TypeSystemOperation where T : ILCodeGenerator
14  {
15 
16  protected UnaryExpression node;
17 
18  protected VisitorILCodeGeneration<T> visitor;
19 
20  protected T codeGenerator;
21 
22  protected int indent;
23 
24  protected object obj;
25 
26  public CGUnaryOperation(VisitorILCodeGeneration<T> visitor, object obj, int indent, UnaryExpression node)
27  {
28  this.codeGenerator = visitor.codeGenerator;
29  this.visitor = visitor;
30  this.obj = obj;
31  this.indent = indent;
32  this.node = node;
33  }
34 
35  public override object Exec(TypeExpression typeExpression, object arg)
36  {
37  if (typeExpression is UnionType)
38  this.Exec(typeExpression as UnionType, arg);
39  if (typeExpression is TypeVariable)
40  this.Exec(typeExpression as TypeVariable, arg);
41  if (typeExpression is PropertyType)
42  this.Exec(((PropertyType)typeExpression).PropertyTypeExpression, arg);
43  else if (typeExpression is FieldType)
44  this.Exec(((FieldType)typeExpression).FieldTypeExpression, arg);
45  else if (IsValueType(typeExpression))
46  {
47  node.Operand.Accept(visitor, obj);
48  GenerateOperator();
49  }
50  return null;
51  }
52 
53  public override object Exec(TypeVariable teLeft, object arg)
54  {
55  if (teLeft.Substitution == null)
56  return this.Exec(GenerateAllUnionTypes(), arg);
57  else
58  return this.Exec(teLeft.Substitution, arg);
59  }
60 
61  public override object Exec(UnionType teLeft, object arg)
62  {
63  node.Operand.Accept(visitor, obj);
64  if (node.Operator == UnaryOperator.Plus || node.Operator == UnaryOperator.Minus)
65  {
66 
67  String finalLabel = this.codeGenerator.NewLabel;
68  String nextLabel = "";
69 
70  List<TypeExpression> typeSet = new List<TypeExpression>();
71  for (int i = 0; i < teLeft.TypeSet.Count; i++)
72  typeSet.AddRange(GetTypes(teLeft.TypeSet[i]));
73  typeSet = new List<TypeExpression>(new HashSet<TypeExpression>(typeSet));
74 
75  for (int i = 0; i < typeSet.Count; i++)
76  {
77  if (!String.IsNullOrEmpty(nextLabel))
78  this.codeGenerator.WriteLabel(indent, nextLabel);
79  if (i != typeSet.Count - 1)
80  {
81  nextLabel = this.codeGenerator.NewLabel;
82  this.codeGenerator.dup(indent);
83  this.codeGenerator.isinst(indent, typeSet[i]);
84  this.codeGenerator.brfalse(indent, nextLabel);
85  }
86  this.codeGenerator.UnboxAny(indent, typeSet[i]);
87  GenerateOperator();
88  this.codeGenerator.Box(indent, typeSet[i]);
89  if (i != typeSet.Count - 1)
90  this.codeGenerator.br(indent, finalLabel);
91  }
92  this.codeGenerator.WriteLabel(indent, finalLabel);
93  }
94  else
95  GenerateOperator();
96  return null;
97  }
98 
99  private UnionType GenerateAllUnionTypes()
100  {
101  UnionType unions = new UnionType();
102  if (node.Operator == UnaryOperator.Plus || node.Operator == UnaryOperator.Minus || node.Operator == UnaryOperator.BitwiseNot)
103  {
104  unions.AddType(CharType.Instance);
105  unions.AddType(IntType.Instance);
106  unions.AddType(DoubleType.Instance);
107  }
108  else if (node.Operator == UnaryOperator.Not)
109  unions.AddType(BoolType.Instance);
110  return unions;
111  }
112 
113  private void GenerateOperator()
114  {
115  switch (node.Operator)
116  {
117  case UnaryOperator.Not:
118  this.codeGenerator.ldc(this.indent, false);
119  this.codeGenerator.ceq(this.indent);
120  break;
121  case UnaryOperator.BitwiseNot:
122  this.codeGenerator.not(this.indent);
123  break;
124  case UnaryOperator.Minus:
125  this.codeGenerator.neg(this.indent);
126  break;
127  case UnaryOperator.Plus:
128  break;
129  default:
130  break;
131  }
132  }
133 
134  private List<TypeExpression> GetTypes(TypeExpression typeExpression)
135  {
136  List<TypeExpression> typeSet = new List<TypeExpression>();
137  if (IsValueType(typeExpression) || typeExpression is StringType)
138  typeSet.Add(typeExpression);
139  else if (typeExpression is TypeVariable)
140  {
141  if (((TypeVariable)typeExpression).Substitution != null)
142  typeSet.AddRange(GetTypes(((TypeVariable)typeExpression).Substitution));
143  }
144  else if (typeExpression is UnionType)
145  {
146  UnionType union = typeExpression as UnionType;
147  foreach (var expression in union.TypeSet)
148  typeSet.AddRange(GetTypes(expression));
149  }
150  return typeSet;
151  }
152 
153  private bool IsValueType(TypeExpression exp)
154  {
155  if (exp is BoolType)
156  return true;
157  if (exp is CharType)
158  return true;
159  if (exp is IntType)
160  return true;
161  if (exp is DoubleType)
162  return true;
163  return false;
164  }
165  }
166 }
Representa a union type.
Definition: UnionType.cs:36
Represent a string type.
Definition: StringType.cs:36
This class represent the entry wnen sending a message to an operation object derived from TypeExpress...
Represent a character type.
Definition: CharType.cs:38
Abstract class that represents all different types.
Represents a generic type expression
Definition: TypeVariable.cs:36
Represent a integer type.
Definition: IntType.cs:37
Represents a double type.
Definition: DoubleType.cs:36
Encapsulates a unary expression of our programming language.
UnaryOperator
Unary operators
Representa a property type.
Definition: PropertyType.cs:34
IList< TypeExpression > TypeSet
Gets the list of type expressions
Definition: UnionType.cs:57
TypeExpression Substitution
Gets the substitution; null if it does not exist
Represent a bool type.
Definition: BoolType.cs:36
Representa a field type.
Definition: FieldType.cs:37