void Write(CiType type) { Write(" : "); if (type is CiStringType) { Write("String"); } else if (type == CiBoolType.Value) { Write("Boolean"); } else if (type == CiByteType.Value || type is CiEnum) { Write("int"); } else if (type is CiArrayType) { Write(((CiArrayType)type).ElementType == CiByteType.Value ? "ByteArray" : "Array"); } else if (type is CiDelegate) { Write("Function"); } else { Write(type.Name); } }
void Write(CiType type) { StringBuilder sb = new StringBuilder(); bool haveConst = false; while (type is CiArrayType) { sb.Insert(0, "[]"); if (!haveConst) { CiArrayPtrType ptr = type as CiArrayPtrType; if (ptr != null && ptr.Writability != PtrWritability.ReadWrite) { sb.Insert(0, ")"); haveConst = true; } } type = ((CiArrayType)type).ElementType; } if (haveConst) { Write("const("); } WriteBaseType(type.BaseType); Write(sb.ToString()); }
protected TypeCode GetTypeCode(CiType type, bool promote) { if (type is CiNumericType) { if (type is CiIntegerType integer) { return(GetIntegerTypeCode(integer, promote)); } if (type == CiSystem.DoubleType) { return(TypeCode.Double); } if (type == CiSystem.FloatType || type == CiSystem.FloatIntType) { return(TypeCode.Single); } throw new NotImplementedException(type.ToString()); } else if (type == CiSystem.BoolType) { return(TypeCode.Boolean); } else if (type == CiSystem.NullType) { return(TypeCode.Empty); } else if (type is CiStringType) { return(TypeCode.String); } return(TypeCode.Object); }
protected override void WriteNew(CiType type) { CiClassStorageType classType = type as CiClassStorageType; if (classType != null) { Write("new "); Write(classType.Class.Name); Write("()"); } else { CiArrayStorageType arrayType = (CiArrayStorageType)type; if (arrayType.ElementType == CiByteType.Value) { Write("new ByteArray()"); } else { Write("new Array("); if (arrayType.LengthExpr != null) { Write(arrayType.LengthExpr); } else { Write(arrayType.Length); } Write(')'); } } }
public override bool IsAssignableFrom(CiType right) { if (right == CiSystem.NullType) { return(true); } CiClass klass = right as CiClass; if (klass == null) { if (!(right is CiClassPtrType ptr)) { return(false); } klass = ptr.Class; } while (klass != Class) { klass = klass.Parent as CiClass; if (klass == null) { return(false); } } // TODO: modifiers return(true); }
protected override void Write(CiType type, bool promote) { switch (type) { case null: Write("void"); break; case CiIntegerType integer: Write(GetTypeCode(integer, promote)); break; case CiStringType _: Write("string"); break; case CiListType list: Write("System.Collections.Generic.List<"); Write(list.ElementType, false); Write('>'); break; case CiArrayType array: Write(array.ElementType, false); Write("[]"); break; default: Write(type.Name); break; } }
public CiMethod(CiCallType callType, CiType type, string name, params CiVar[] parameters) { this.CallType = callType; this.Type = type; this.Name = name; this.Parameters.AddRange(parameters); }
protected override void WriteNewStorage(CiType type) { switch (type) { case CiListType list: Write("new List"); WriteElementType(list); Write("()"); break; case CiStackType stack: Write("new Stack"); WriteElementType(stack); Write("()"); break; case CiHashSetType set: Write("new HashSet"); WriteElementType(set); Write("()"); break; case CiDictionaryType dict: Write("new "); Write(dict); Write("()"); break; default: base.WriteNewStorage(type); break; } }
public override bool IsAssignableFrom(CiType right) { if (right == CiSystem.NullType) { return(true); } if (!(right is CiArrayType array) || !array.ElementType.Equals(this.ElementType)) { return(false); } switch (this.Modifier) { case CiToken.EndOfFile: return(true); case CiToken.ExclamationMark: return(!(array is CiArrayPtrType ptr) || ptr.Modifier != CiToken.EndOfFile); case CiToken.Hash: return(array is CiArrayPtrType dynamicPtr && dynamicPtr.Modifier == CiToken.Hash); default: throw new NotImplementedException(this.Modifier.ToString()); } }
void Write(CiField field) { Write(field.Documentation); Write("this."); WriteCamelCase(field.Name); CiType type = field.Type; if (type == CiBoolType.Value) { Write(" = false"); } else if (type == CiByteType.Value || type == CiIntType.Value) { Write(" = 0"); } else if (type is CiEnum) { Write(" = "); WriteConst(((CiEnum)type).Values[0]); } else if (!WriteInit(type)) { Write(" = null"); } WriteLine(";"); }
protected override string ToString(CiType type) { if (type == CiBoolType.Value) { return("cibool"); } return(type.Name); }
public CiMethod(CiType returnType, string name, params CiParam[] paramz) { this.Name = name; this.CallType = CiCallType.Normal; this.Signature = new CiDelegate { Name = name, ReturnType = returnType, Params = paramz }; }
protected void WriteCoercedLiterals(CiType type, CiExpr[] exprs) { for (int i = 0; i < exprs.Length; i++) { WriteComma(i); WriteCoercedLiteral(type, ((CiLiteral)exprs[i]).Value); } }
protected override void WriteCoercedLiteral(CiType type, CiExpr literal) { literal.Accept(this, CiPriority.Argument); if (type == CiSystem.FloatType) { Write('f'); } }
protected override void WriteStaticCast(CiType type, CiExpr expr) { Write("static_cast<"); Write(type, false); Write(">("); GetStaticCastInner(type, expr).Accept(this, CiPriority.Statement); Write(')'); }
public override CiExpr Visit(CiAggregateInitializer expr, CiPriority parent) { CiType type = ((CiArrayStorageType)expr.Type).ElementType; Write("[ "); WriteCoercedLiterals(type, expr.Items); Write(" ]"); return(expr); }
protected override void WriteNewArray(CiType elementType, CiExpr lengthExpr, CiPriority parent) { Include("memory"); Write("std::make_shared<"); Write(elementType, false); Write("[]>("); lengthExpr.Accept(this, CiPriority.Statement); Write(')'); }
protected override void WriteNewArray(CiType elementType, CiExpr lengthExpr, CiPriority parent) { Write("new "); if (elementType is CiNumericType numeric) { Write(GetArrayElementType(numeric)); } WriteCall("Array", lengthExpr); }
void Write(CiType type) { WriteBaseType(type.BaseType); for (int i = 0; i < type.ArrayLevel; i++) { Write("[]"); } Write(' '); }
public override CiExpr Visit(CiCollection expr, CiPriority parent) { CiType type = ((CiArrayStorageType)expr.Type).ElementType; Write("{ "); WriteCoercedLiterals(type, expr.Items); Write(" }"); return(expr); }
bool WriteInit(CiType type) { if (type is CiClassStorageType || type is CiArrayStorageType) { Write(" = "); WriteNew(type); return(true); } return(false); }
protected void WriteCoerced(CiType type, CiExpr expr, CiPriority parent) { if (expr is CiCondExpr cond) { WriteCoerced(type, cond, parent); } else { WriteCoercedInternal(type, expr, parent); } }
void WriteBaseType(CiType type) { if (type is CiStringType) { Write("string"); } else { Write(type.Name); } }
protected void WriteCoerced(CiType type, CiExpr expr, CiPriority parent) { if (expr is CiSelectExpr select) { WriteCoerced(type, select, parent); } else { WriteCoercedInternal(type, expr, parent); } }
protected override void WriteNew(CiType type) { Write("new "); WriteBaseType(type.BaseType); CiArrayStorageType arrayType = type as CiArrayStorageType; if (arrayType != null) { WriteInitializer(arrayType); } }
protected void WriteNewStorage(CiType type) { if (type is CiClass klass) { WriteNew(klass, CiPriority.Statement); } else if (type is CiArrayStorageType array) { WriteNewArray(array); } }
void WriteBaseType(CiType type) { if (type == CiSystem.MatchClass) { Include("regex"); Write("std::cmatch"); } else { Write(type.Name); } }
protected override void WriteNewArray(CiType elementType, CiExpr lengthExpr, CiPriority parent) { Write("new "); Write(elementType.BaseType, false); Write('['); lengthExpr.Accept(this, CiPriority.Statement); Write(']'); while (elementType is CiArrayType array) { Write("[]"); elementType = array.ElementType; } }
void WriteListType(CiType elementType) { if (elementType.IsPointer) { Write('('); } Write(elementType, false); if (elementType.IsPointer) { Write(')'); } Write("[]"); }
protected override void Write(CiType type, bool promote) { switch (type) { case CiIntegerType integer: Write(GetIntegerTypeCode(integer, promote)); break; case CiStringType _: Write("string"); break; case CiListType list: Write("List"); WriteElementType(list); break; case CiStackType stack: Write("Stack"); WriteElementType(stack); break; case CiHashSetType set: Write("HashSet"); WriteElementType(set); break; case CiDictionaryType dict: Write(dict); break; case CiArrayType array: Write(array.ElementType, false); Write("[]"); break; case CiClass klass: WriteClassName(klass); break; case CiClassPtrType classPtr: WriteClassName(classPtr.Class); break; default: Write(type.Name); break; } }
public override bool Equals(CiType obj) { CiArrayPtrType that = obj as CiArrayPtrType; return that != null && this.ElementType.Equals(that.ElementType); }
protected override void WriteNew(CiType type) { CiClassStorageType classType = type as CiClassStorageType; if (classType != null) { Write("new "); Write(classType.Class.Name); Write("()"); } else { CiArrayStorageType arrayType = (CiArrayStorageType) type; Write("new "); WriteBaseType(arrayType.BaseType); WriteInitializer(arrayType); } }
void WriteBaseType(CiType type) { if (type is CiStringType) Write("String"); else if (type == CiBoolType.Value) Write("boolean"); else if (type is CiEnum) Write("int"); else Write(type.Name); }
static void CheckCopyPtr(CiType target, CiMaybeAssign source) { ICiPtrType tp = target as ICiPtrType; if (tp == null) return; CiCondExpr cond = source as CiCondExpr; if (cond != null) { CheckCopyPtr(target, cond.OnTrue); CheckCopyPtr(target, cond.OnFalse); return; } for (;;) { while (source is CiCoercion) source = ((CiCoercion) source).Inner; ICiPtrType sp = source.Type as ICiPtrType; if (sp != null) { tp.Sources.Add(sp); break; } if (source is CiFieldAccess) source = ((CiFieldAccess) source).Obj; else if (source is CiArrayAccess) source = ((CiArrayAccess) source).Array; else break; } }
void Write(CiType type) { Write(" : "); if (type is CiStringType) Write("String"); else if (type == CiBoolType.Value) Write("Boolean"); else if (type == CiByteType.Value || type is CiEnum) Write("int"); else if (type is CiArrayType) Write(((CiArrayType) type).ElementType == CiByteType.Value ? "ByteArray" : "Array"); else if (type is CiDelegate) Write("Function"); else Write(type.Name); }
protected override string ToString(CiType type) { if (type == CiBoolType.Value) return "cibool"; return type.Name; }
static object GetErrorValue(CiType type) { if (type == CiType.Void) return false; if (type == CiIntType.Value) return -1; if (type == CiStringPtrType.Value || type is CiClassPtrType || type is CiArrayPtrType) return null; throw new ResolveException("throw in a method of unsupported return type"); }
object ResolveConstInitializer(ref CiType type, object value) { if (type is CiArrayType) { object[] array = value as object[]; if (array == null) return value; CiType elementType = ((CiArrayType) type).ElementType; if (type is CiArrayStorageType) { int expected = ((CiArrayStorageType) type).Length; if (array.Length != expected) throw new ResolveException("Expected {0} array elements, got {1}", expected, array.Length); } else { type = new CiArrayStorageType { ElementType = elementType, Length = array.Length }; } Array dest = Array.CreateInstance(elementType.DotNetType, array.Length); for (int i = 0; i < array.Length; i++) dest.SetValue(ResolveConstInitializer(ref elementType, array[i]), i); return dest; } if (value is CiExpr) return ResolveConstExpr((CiExpr) value, type); return value; }
object ResolveConstExpr(CiExpr expr, CiType type) { expr = Coerce(Resolve(expr), type); CiConstExpr ce = expr as CiConstExpr; if (ce == null) throw new ResolveException("{0} is not constant", expr); return ce.Value; }
protected abstract void WriteNew(CiType type);
public CiParam(CiType type, string name) { this.Type = type; this.Name = name; }
public override bool Equals(CiType obj) { CiStringStorageType that = obj as CiStringStorageType; return that != null && this.Length == that.Length; }
public virtual bool Equals(CiType obj) { return this == obj; }
CiMaybeAssign Coerce(CiMaybeAssign expr, CiType expected) { CiType got = expr.Type; if (expected.Equals(got)) return expr; if (expected == CiIntType.Value && got == CiByteType.Value) { CiConstExpr konst = expr as CiConstExpr; if (konst != null) return new CiConstExpr((object) (int) (byte) konst.Value); CiCondExpr cond = expr as CiCondExpr; if (cond != null && (cond.OnTrue is CiConstExpr || cond.OnFalse is CiConstExpr)) { // avoid ((foo ? 1 : 0) & 0xff) in Java return Coerce(cond, expected); } if (expr is CiArrayAccess) { CiConstAccess ca = ((CiArrayAccess) expr).Array as CiConstAccess; if (ca != null && ca.Const.Is7Bit) return expr; } return new CiCoercion { ResultType = expected, Inner = expr }; } if (expected == CiByteType.Value && got == CiIntType.Value) { CiConstExpr konst = expr as CiConstExpr; if (konst != null) return new CiConstExpr((object) (byte) (int) konst.Value); return new CiCoercion { ResultType = expected, Inner = expr }; } if (expected == CiStringPtrType.Value && (got == CiType.Null || got is CiStringType)) return expr; if (expected is CiStringStorageType && got is CiStringType) return expr; if (expected is CiClassType) { if (got == CiType.Null) return expr; if (Extends(got, ((CiClassType) expected).Class)) { if (expr is CiCondExpr) { // C doesn't like &(cond ? foo : bar) return Coerce((CiCondExpr) expr, expected); } return new CiCoercion { ResultType = expected, Inner = expr }; } } if (expected is CiArrayPtrType) { if (got == CiType.Null) return expr; CiArrayType gotArray = got as CiArrayType; if (got != null && ((CiArrayPtrType) expected).ElementType.Equals(gotArray.ElementType)) return new CiCoercion { ResultType = expected, Inner = expr }; } throw new ResolveException("Expected {0}, got {1}", expected, got); }
CiType Resolve(CiType type) { return type.Accept(this); }
CiCondExpr Coerce(CiCondExpr expr, CiType expected) { return new CiCondExpr { Cond = expr.Cond, ResultType = expected, OnTrue = Coerce(expr.OnTrue, expected), OnFalse = Coerce(expr.OnFalse, expected) }; }
CiType ParseArrayType(CiType baseType) { if (Eat(CiToken.LeftBracket)) { if (Eat(CiToken.RightBracket)) return new CiArrayPtrType { ElementType = ParseArrayType(baseType) }; CiExpr len = ParseExpr(); Expect(CiToken.RightBracket); return new CiArrayStorageType { LengthExpr = len, ElementType = ParseArrayType(baseType) }; } return baseType; }
void CheckCreatable(CiType type) { CiClass storageClass = type.StorageClass; if (storageClass != null && storageClass.IsAbstract) throw new ResolveException("Cannot create instances of an abstract class {0}", storageClass.Name); }
object ParseConstInitializer(CiType type) { if (type is CiArrayType) { Expect(CiToken.LeftBrace); CiType elementType = ((CiArrayType) type).ElementType; List<object> list = new List<object>(); if (!See(CiToken.RightBrace)) { do list.Add(ParseConstInitializer(elementType)); while (Eat(CiToken.Comma)); } Expect(CiToken.RightBrace); return list.ToArray(); } return ParseExpr(); }
static bool Extends(CiType type, CiClass baseClass) { if (!(type is CiClassType)) return false; CiClass klass = ((CiClassType) type).Class; while (klass != baseClass) { // TODO: resolve, make sure no loops klass = klass.BaseClass; if (klass == null) return false; } return true; }
protected override void WriteNew(CiType type) { Write("new "); WriteBaseType(type.BaseType); CiArrayStorageType arrayType = type as CiArrayStorageType; if (arrayType != null) WriteInitializer(arrayType); }
protected override void WriteNew(CiType type) { CiClassStorageType classType = type as CiClassStorageType; if (classType != null) { Write("new "); Write(classType.Class.Name); Write("()"); } else { CiArrayStorageType arrayType = (CiArrayStorageType) type; if (arrayType.ElementType == CiByteType.Value) Write("new ByteArray()"); else { Write("new Array("); if (arrayType.LengthExpr != null) Write(arrayType.LengthExpr); else Write(arrayType.Length); Write(')'); } } }
void Write(CiType type) { StringBuilder sb = new StringBuilder(); bool haveConst = false; while (type is CiArrayType) { sb.Insert(0, "[]"); if (!haveConst) { CiArrayPtrType ptr = type as CiArrayPtrType; if (ptr != null && ptr.Writability != PtrWritability.ReadWrite) { sb.Insert(0, ")"); haveConst = true; } } type = ((CiArrayType) type).ElementType; } if (haveConst) Write("const("); WriteBaseType(type.BaseType); Write(sb.ToString()); }
string ToString(CiType type, string s) { StringBuilder sb = new StringBuilder(s); bool needParens = false; while (type is CiArrayType) { CiArrayStorageType stg = type as CiArrayStorageType; if (stg != null) { if (needParens) { sb.Insert(0, '('); sb.Append(')'); needParens = false; } sb.Append('['); sb.Append(stg.Length); sb.Append(']'); } else { InsertPtr(sb, ((CiArrayPtrType) type).Writability); needParens = true; } type = ((CiArrayType) type).ElementType; } if (type is CiByteType) sb.Insert(0, "unsigned char "); else if (type is CiStringPtrType) sb.Insert(0, "const char *"); else if (type is CiStringStorageType) { if (needParens) { sb.Insert(0, '('); sb.Append(')'); } sb.Insert(0, "char "); sb.Append('['); sb.Append(((CiStringStorageType) type).Length + 1); sb.Append(']'); } else { if (type is CiClassPtrType) InsertPtr(sb, ((CiClassPtrType) type).Writability); sb.Insert(0, ' '); sb.Insert(0, ToString(type)); } return sb.ToString(); }
void WriteBaseType(CiType type) { if (type is CiStringType) Write("string"); else Write(type.Name); }
void Write(CiType type) { WriteBaseType(type.BaseType); for (int i = 0; i < type.ArrayLevel; i++) Write("[]"); Write(' '); }
CiExpr Coerce(CiExpr expr, CiType expected) { return (CiExpr) Coerce((CiMaybeAssign) expr, expected); }
bool WriteInit(CiType type) { if (type is CiClassStorageType || type is CiArrayStorageType) { Write(" = "); WriteNew(type); return true; } return false; }
public override bool Equals(CiType obj) { CiClassStorageType that = obj as CiClassStorageType; return that != null && this.Class == that.Class; }