Esempio n. 1
0
        public GamaValueRef VisitExpression(GamaTypeRef target, GamaParser.ExprContext exp)
        {
            ExpressionCompiler.PushTT(target);
            var result = ExpressionCompiler.Visit(exp);

            ExpressionCompiler.PopTT();
            return(result);
        }
Esempio n. 2
0
        public override bool VisitTopLevelStructDef([NotNull] GamaParser.TopLevelStructDefContext context)
        {
            var symtype = context.symbolTypePairList();

            if (symtype == null)
            {
                GlobalContext.AddError(new ErrorEmptyStruct(context));
                return(false);
            }
            var structname = context.Symbol().GetText();

            if (NamespaceContext.FindTypeRef(structname) != null)
            {
                GlobalContext.AddError(new ErrorDuplicateType(context));
                return(false);
            }

            var pairs  = symtype.symbolTypePair();
            var fields = new Dictionary <string, GamaFieldRef>(pairs.Length);
            var types  = new LLVMTypeRef[pairs.Length];
            var packed = context.Packed() != null;

            for (int i = 0; i < pairs.Length; i++)
            {
                var p    = pairs[i];
                var name = p.Symbol().GetText();
                if (fields.ContainsKey(name))
                {
                    GlobalContext.AddError(new ErrorDuplicateField(p));
                    return(false);
                }
                var ty = NamespaceContext.FindTypeRefGlobal(p.typeName());
                if (ty == null)
                {
                    GlobalContext.AddError(new ErrorTypeNotFound(p.typeName()));
                    return(false);
                }
                fields[name] = new GamaFieldRef(name, i, ty);
                types[i]     = ty.UnderlyingType;
            }

            LLVMTypeRef nativety;

            unsafe {
                nativety = LLVM.StructCreateNamed(GlobalContext.Context, structname.GetSbytePtr());
                nativety.StructSetBody(types, packed);
            }
            var structty = new GamaTypeRef(structname, nativety);

            structty.Meta.Fields.AddRange(fields.Values);
            NamespaceContext.This.Types.Add(structty);

            return(true);
        }
Esempio n. 3
0
        public override bool VisitTopLevelDelegate([NotNull] GamaParser.TopLevelDelegateContext context)
        {
            var name = context.Symbol().GetText();

            if (NamespaceContext.FindTypeRef(name) != null)
            {
                GlobalContext.AddError(new ErrorDuplicateType(context));
                return(false);
            }

            var retty = InstanceTypes.Void;

            var rettyfqtn = context.fqtn();

            if (rettyfqtn != null)
            {
                retty = NamespaceContext.FindTypeRefGlobal(rettyfqtn);
                if (retty == null)
                {
                    GlobalContext.AddError(new ErrorTypeNotFound(context.fqtn()));
                    return(false);
                }
            }

            var parms       = new GamaTypeRef[0];
            var parmsnative = new LLVMTypeRef[0];
            var parmsctx    = context.fqtnList();

            if (parmsctx != null)
            {
                var fqtns = parmsctx.fqtn();
                parms       = new GamaTypeRef[fqtns.Length];
                parmsnative = new LLVMTypeRef[fqtns.Length];
                for (int i = 0; i < fqtns.Length; i++)
                {
                    var ty = NamespaceContext.FindTypeRefGlobal(fqtns[i]);
                    if (ty == null)
                    {
                        GlobalContext.AddError(new ErrorTypeNotFound(fqtns[i]));
                        return(false);
                    }
                    parms[i]       = ty;
                    parmsnative[i] = ty.UnderlyingType;
                }
            }
            NamespaceContext.This.Types.Add(new GamaFunction(name, retty, parms, LLVMTypeRef.CreateFunction(retty.UnderlyingType, parmsnative)));
            return(true);
        }
Esempio n. 4
0
 /* Checks if another function type is compatible with this one                          */
 /* Mainly useful for assigning function to variables or sending functions as parameters */
 /* Check Units.GamaExpressionCompiler.cs for target type stack implementation           */
 public override bool Compatible(GamaTypeRef other)
 {
     if (!(other is GamaFunction fnt))
     {
         return(false);                              // Non-compatible with non function types
     }
     if (fnt.ReturnType != ReturnType || ParameterTypes.Length != fnt.ParameterTypes.Length)
     {
         return(false);
     }
     for (int i = 0; i < ParameterTypes.Length; i++)
     {
         if (!fnt.ParameterTypes[i].IsSubtypeOf(ParameterTypes[i]))
         {
             return(false);
         }
     }
     return(true);
 }
Esempio n. 5
0
 public GamaFunction(GamaTypeRef ret, GamaTypeRef[] parms, LLVMTypeRef fntype, bool vararg = false) : base("[internal]", fntype)
 {
     ReturnType     = ret;
     ParameterTypes = parms;
     IsVarArg       = vararg;
 }
Esempio n. 6
0
 public override bool Compatible(GamaTypeRef other)
 {
     return(other is GamaPointer ptr && ptr.BaseType.Compatible(BaseType));
     // return base.Compatible(other);
 }
Esempio n. 7
0
 public GamaFunction(GamaTypeRef ret, GamaTypeRef[] parms, bool vararg = false) : base("", null)
 {
     ReturnType     = ret;
     ParameterTypes = parms;
     IsVarArg       = vararg;
 }
Esempio n. 8
0
 public GamaFunction(string name, GamaTypeRef ret, GamaTypeRef[] parms, LLVMTypeRef fntype, bool vararg = false) : base(name, fntype)
 {
     ReturnType     = ret;
     ParameterTypes = parms;
     IsVarArg       = vararg;
 }
Esempio n. 9
0
        public override GamaValueRef VisitExprIndex([NotNull] GamaParser.ExprIndexContext context)
        {
            var val = Visit(context.expr());

            if (val == null)
            {
                return(null);
            }

            var exprs = context.exprList().expr();

            var builder = Parent.Builder;

            if (!IsEmptyTT)
            {
                var tt         = TopTT;
                var vals       = new GamaValueRef[exprs.Length];
                var valsnative = new LLVMValueRef[exprs.Length];
                var tys        = new GamaTypeRef[exprs.Length];

                for (int i = 0; i < vals.Length; i++)
                {
                    var tmp = Visit(exprs[i]);
                    if (tmp == null)
                    {
                        return(null);
                    }
                    vals[i]       = tmp;
                    valsnative[i] = tmp.Value;
                    tys[i]        = tmp.Type;
                }

                var cbcomp = val.Type.Meta.CompiledOperators.Index.FindFunction(tt, tys);
                if (cbcomp == null)
                {
                    var cb = val.Type.Meta.Operators.Index.FindFunction(tt, tys);
                    if (cb == null)
                    {
                        Parent.NamespaceContext.Context.AddError(new ErrorNoViableOperator(context));
                        return(null);
                    }
                    Parent.CurrentBlock.PositionBuilderAtEnd(builder);
                    return(new GamaValueRef(cb.ReturnType, builder.BuildCall(cb.Value, valsnative), false)); // TODO: make indexing assignable
                }
                return(cbcomp.Call(builder, vals));
            }
            else
            {
                var vals       = new GamaValueRef[exprs.Length];
                var valsnative = new LLVMValueRef[exprs.Length];
                var tys        = new GamaTypeRef[exprs.Length];

                for (int i = 0; i < vals.Length; i++)
                {
                    var tmp = Visit(exprs[i]);
                    if (tmp == null)
                    {
                        return(null);
                    }
                    vals[i]       = tmp;
                    valsnative[i] = tmp.Value;
                    tys[i]        = tmp.Type;
                }

                var cbcomp = val.Type.Meta.CompiledOperators.Index.FindFunction(tys);
                if (cbcomp == null)
                {
                    var cb = val.Type.Meta.Operators.Index.FindFunction(tys);
                    if (cb == null)
                    {
                        Parent.NamespaceContext.Context.AddError(new ErrorNoViableOperator(context));
                        return(null);
                    }
                    Parent.CurrentBlock.PositionBuilderAtEnd(builder);
                    return(new GamaValueRef(cb.ReturnType, builder.BuildCall(cb.Value, valsnative), false)); // TODO: make indexing assignable
                }
                return(cbcomp.Call(builder, vals));
            }
        }
Esempio n. 10
0
        public override bool VisitTopLevelFuncDef([NotNull] GamaParser.TopLevelFuncDefContext context)
        {
            var name   = context.Symbol().GetText();
            var fnlist = NamespaceContext.FindFunctionRef(name);
            var attrs  = context.funcAttr();

            // New function
            if (fnlist == null)
            {
                fnlist = new GamaFunctionList(name);
                var stplist         = context.symbolTypePairList();
                var parms           = new GamaParamList();
                var parmTypes       = new GamaTypeRef[0];
                var parmTypesNative = new LLVMTypeRef[0];

                if (stplist != null)
                {
                    var list = stplist.symbolTypePair();

                    parmTypes       = new GamaTypeRef[list.Length];
                    parmTypesNative = new LLVMTypeRef[list.Length];

                    for (int i = 0; i < list.Length; i++)
                    {
                        var stp  = list[i];
                        var sym  = stp.Symbol();
                        var type = NamespaceContext.FindTypeRefGlobal(stp.typeName());
                        if (type == null)
                        {
                            GlobalContext.AddError(new ErrorTypeNotFound(stp.typeName()));
                            return(false);
                        }
                        /* Since functions are not first-class types, we need to wrap them around with a pointer */
                        if (type is GamaFunction)
                        {
                            type = new GamaPointer(type);
                        }
                        if (!parms.Add(sym.GetText(), type))
                        {
                            GlobalContext.AddError(new ErrorDuplicateParameter(stp));
                            return(false); // TODO: fix error library.
                        }
                        parmTypesNative[i] = type.UnderlyingType;
                        parmTypes[i]       = type;
                    }
                }

                /* Determine type */
                var rettypefqtn = context.typeName();
                var retty       = InstanceTypes.Void;

                // If function has a non-void type
                if (rettypefqtn != null)
                {
                    // Find it
                    retty = NamespaceContext.FindTypeRefGlobal(rettypefqtn);
                    if (retty == null)
                    {
                        GlobalContext.AddError(new ErrorTypeNotFound(rettypefqtn));
                        return(false);
                    }
                }

                /* LLVM */
                var modty = new GamaFunction(retty, parmTypes, LLVMTypeRef.CreateFunction(retty.UnderlyingType, parmTypesNative));
                var modfn = NamespaceContext.This.Context.Module.AddFunction(name, modty.UnderlyingType);

                var fn   = new GamaFunctionRef(retty, parms, modty, modfn, false);
                var unit = new GamaFunctionCompiler(NamespaceContext, fn);

                /* Parameters are added to top frame of the target function, but they are not treated as conventional variables */
                foreach (var p in parms.Parameters)
                {
                    unit.Top.AddValue(p.Name, new GamaValueRef(p.Type, modfn.GetParam(p.Index), false));
                }

                unit.Visit(context.block());
                if (unit.Finish() == 0)
                {
                    // First add ident, if it fails you fail too.
                    if (attrs != null)
                    {
                        var attributes = new GamaAttributeCompiler(this).Visit(attrs);
                        if (attributes != null)
                        {
                            fn.Attributes = attributes;
                        }
                        else
                        {
                            return(false);
                        }
                    }
                    fnlist.AddFunction(fn);
                    NamespaceContext.This.Functions.Add(fnlist);
                }
                else
                {
                    ; // ?gnihtemos oD :ODOT (TODO:)
                }
                return(true);
            }
            // An override function
            else
            {
                var stplist = context.symbolTypePairList();
                var parms   = new GamaParamList();
                if (stplist != null)
                {
                    var list = stplist.symbolTypePair();
                    for (int i = 0; i < list.Length; i++)
                    {
                        var stp  = list[i];
                        var sym  = stp.Symbol();
                        var type = NamespaceContext.FindTypeRefGlobal(stp.typeName());
                        if (type == null)
                        {
                            GlobalContext.AddError(new ErrorTypeNotFound(stp.typeName()));
                            return(false);
                        }
                        if (type is GamaFunction)
                        {
                            if (!parms.Add(sym.GetText(), new GamaPointer(type)))
                            {
                                GlobalContext.AddError(new ErrorDuplicateParameter(stp));
                                return(false); // TODO: fix error library.
                            }
                            continue;
                        }
                        if (!parms.Add(sym.GetText(), type))
                        {
                            GlobalContext.AddError(new ErrorDuplicateParameter(stp));
                            return(false);
                        }
                    }
                }

                // Duplicate function if two functions have same type of parameters
                if (fnlist.FindFunction(parms) != null)
                {
                    GlobalContext.AddError(new ErrorDuplicateFunction(context));
                    return(false);
                }

                /* Determine type */
                var rettypefqtn = context.typeName();
                var retty       = InstanceTypes.Void;

                // If function has a non-void type
                if (rettypefqtn != null)
                {
                    // Find it
                    retty = NamespaceContext.FindTypeRefGlobal(rettypefqtn);
                    if (retty == null)
                    {
                        GlobalContext.AddError(new ErrorTypeNotFound(rettypefqtn));
                        return(false);
                    }
                }

                var modty = new GamaFunction(retty, parms.Parameters.Select(p => p.Type).ToArray(), LLVMTypeRef.CreateFunction(retty.UnderlyingType, parms.Parameters.Select(p => p.Type.UnderlyingType).ToArray()));
                var modfn = GlobalContext.Module.AddFunction(name, modty.UnderlyingType);

                var fn   = new GamaFunctionRef(retty, parms, modty, modfn, false);
                var unit = new GamaFunctionCompiler(NamespaceContext, fn);
                unit.Visit(context.block());
                if (unit.Finish() == 0)
                {
                    if (attrs != null)
                    {
                        var attributes = new GamaAttributeCompiler(this).Visit(attrs);
                        if (attributes != null)
                        {
                            fn.Attributes = attributes;
                        }
                        else
                        {
                            return(false);
                        }
                    }
                    fnlist.AddFunction(fn);
                }
                else
                {
                    ; // TODO:
                }
                return(true);
            }
        }
Esempio n. 11
0
 public GamaStructCompiler(GamaTopLevelCompiler parent, GamaTypeRef structty)
 {
     Parent     = parent;
     StructType = structty;
 }
Esempio n. 12
0
 /* Target type manipulators */
 public void PushTT(GamaTypeRef type) => TargetTypeStack.Push(type);
Esempio n. 13
0
        public override bool VisitTopLevelExternDef([NotNull] GamaParser.TopLevelExternDefContext context)
        {
            var name = context.Symbol().GetText();
            var list = NamespaceContext.FindFunctionRefGlobal(name);

            if (list == null)
            {
                list = new GamaFunctionList(name);
                NamespaceContext.This.Functions.Add(list);
            }

            var retty = InstanceTypes.Void;

            var rettyfqtn = context.typeName();

            if (rettyfqtn != null)
            {
                retty = NamespaceContext.FindTypeRefGlobal(rettyfqtn);
                if (retty == null)
                {
                    GlobalContext.AddError(new ErrorTypeNotFound(context.typeName()));
                    return(false);
                }
            }

            var ellipsis       = context.ellipsis() != null;
            var parmslist      = new GamaParamList();
            var argtypes       = new GamaTypeRef[0];
            var argtypesnative = new LLVMTypeRef[0];
            var fqtnlist       = context.typeList();

            if (fqtnlist != null)
            {
                var types = fqtnlist.typeName();
                argtypesnative = new LLVMTypeRef[types.Length];
                argtypes       = new GamaTypeRef[types.Length];
                for (int i = 0; i < types.Length; i++)
                {
                    var ty = NamespaceContext.FindTypeRefGlobal(types[i]);
                    if (ty == null)
                    {
                        GlobalContext.AddError(new ErrorTypeNotFound(types[i]));
                        return(false);
                    }
                    parmslist.Add(i.ToString(), ty); // Adding parameter with a numeric name, doesn't matter since this is a extern.
                    argtypes[i]       = ty;
                    argtypesnative[i] = ty.UnderlyingType;
                }
            }

            if (list.FindFunction(parmslist) != null)
            {
                GlobalContext.AddError(new ErrorDuplicateFunction(context));
                return(false);
            }

            var fnty  = new GamaFunction(retty, argtypes, LLVMTypeRef.CreateFunction(retty.UnderlyingType, argtypesnative, ellipsis), ellipsis);
            var modfn = GlobalContext.Module.AddFunction(name, fnty.UnderlyingType);

            var fnref = new GamaFunctionRef(retty, parmslist, fnty, modfn, false);

            list.AddFunction(fnref);

            return(true);
        }
Esempio n. 14
0
 public GamaPointer(GamaTypeRef basetype) : base("[pointer]", LLVMTypeRef.CreatePointer(basetype.UnderlyingType, 0))
 {
     BaseType = basetype;
 }
Esempio n. 15
0
 public GamaPointer(string name, GamaTypeRef basetype) : base(name, LLVMTypeRef.CreatePointer(basetype.UnderlyingType, 0))
 {
     BaseType = basetype;
 }
Esempio n. 16
0
 public override bool Compatible(GamaTypeRef other)
 {
     return(other is GamaArray a && a.ElementType == ElementType);
 }
Esempio n. 17
0
 public GamaArray(GamaTypeRef elemtype, int size) : base($"{ elemtype.Name }[{ size }]", LLVMTypeRef.CreateArray(elemtype.UnderlyingType, (uint)size))
 {
     ElementType = elemtype;
 }