public GamaValueRef VisitExpression(GamaTypeRef target, GamaParser.ExprContext exp) { ExpressionCompiler.PushTT(target); var result = ExpressionCompiler.Visit(exp); ExpressionCompiler.PopTT(); return(result); }
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); }
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); }
/* 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); }
public GamaFunction(GamaTypeRef ret, GamaTypeRef[] parms, LLVMTypeRef fntype, bool vararg = false) : base("[internal]", fntype) { ReturnType = ret; ParameterTypes = parms; IsVarArg = vararg; }
public override bool Compatible(GamaTypeRef other) { return(other is GamaPointer ptr && ptr.BaseType.Compatible(BaseType)); // return base.Compatible(other); }
public GamaFunction(GamaTypeRef ret, GamaTypeRef[] parms, bool vararg = false) : base("", null) { ReturnType = ret; ParameterTypes = parms; IsVarArg = vararg; }
public GamaFunction(string name, GamaTypeRef ret, GamaTypeRef[] parms, LLVMTypeRef fntype, bool vararg = false) : base(name, fntype) { ReturnType = ret; ParameterTypes = parms; IsVarArg = vararg; }
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)); } }
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); } }
public GamaStructCompiler(GamaTopLevelCompiler parent, GamaTypeRef structty) { Parent = parent; StructType = structty; }
/* Target type manipulators */ public void PushTT(GamaTypeRef type) => TargetTypeStack.Push(type);
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); }
public GamaPointer(GamaTypeRef basetype) : base("[pointer]", LLVMTypeRef.CreatePointer(basetype.UnderlyingType, 0)) { BaseType = basetype; }
public GamaPointer(string name, GamaTypeRef basetype) : base(name, LLVMTypeRef.CreatePointer(basetype.UnderlyingType, 0)) { BaseType = basetype; }
public override bool Compatible(GamaTypeRef other) { return(other is GamaArray a && a.ElementType == ElementType); }
public GamaArray(GamaTypeRef elemtype, int size) : base($"{ elemtype.Name }[{ size }]", LLVMTypeRef.CreateArray(elemtype.UnderlyingType, (uint)size)) { ElementType = elemtype; }