protected override Type resolve(Context ctx, bool mustReturn) { if(Identifier == "_") error(CompilerMessages.UnderscoreNameUsed); // local variable var local = Local ?? ctx.Scope.FindLocal(Identifier); if (local != null) { // only local constants are cached // because mutable variables could be closured later on if (local.IsConstant && local.IsImmutable && ctx.Options.UnrollConstants) _LocalConstant = local; return local.Type; } // static function declared in the script try { var methods = ctx.MainType.ResolveMethodGroup(Identifier); if (methods.Length > 1) error(CompilerMessages.FunctionInvocationAmbiguous, Identifier); _Method = methods[0]; return FunctionalHelper.CreateFuncType(_Method.ReturnType, _Method.GetArgumentTypes(ctx)); } catch (KeyNotFoundException) { } // algebraic type without a constructor var type = ctx.FindType(Identifier); if (type != null && type.Kind == TypeEntityKind.TypeLabel) { try { type.ResolveConstructor(new Type[0]); _Type = type; return _Type.TypeInfo; } catch (KeyNotFoundException) { } } // global property try { _Property = ctx.ResolveGlobalProperty(Identifier); return _Property.PropertyType; } catch (KeyNotFoundException) { error(CompilerMessages.IdentifierNotFound, Identifier); } return typeof (UnitType); }
protected override void compile(Context ctx, bool mustReturn) { var gen = ctx.CurrentILGenerator; var exprType = Value.GetExpressionType(ctx); ctx.CheckTypedExpression(Value, exprType, true); var nameInfo = LocalName ?? ctx.CurrentScope.FindName(Identifier); if (nameInfo != null) { if (nameInfo.IsImmutable && !IsInitialization) Error(CompilerMessages.IdentifierIsConstant, Identifier); if (!nameInfo.Type.IsExtendablyAssignableFrom(exprType)) Error(CompilerMessages.IdentifierTypeMismatch, exprType, nameInfo.Type); if (nameInfo.IsClosured) { if (nameInfo.ClosureDistance == 0) assignClosuredLocal(ctx, nameInfo); else assignClosuredRemote(ctx, nameInfo); } else { assignLocal(ctx, nameInfo); } return; } try { var pty = ctx.ResolveGlobalProperty(Identifier); if(!pty.HasSetter) Error(CompilerMessages.GlobalPropertyNoSetter, Identifier); var type = pty.PropertyType; if(!type.IsExtendablyAssignableFrom(exprType)) Error(CompilerMessages.GlobalPropertyTypeMismatch, exprType, type); var cast = Expr.Cast(Value, type); if (pty.SetterMethod != null) { cast.Compile(ctx, true); gen.EmitCall(pty.SetterMethod.MethodInfo); } else { var method = typeof (GlobalPropertyHelper).GetMethod("Set").MakeGenericMethod(type); gen.EmitConstant(ctx.ContextId); gen.EmitConstant(pty.PropertyId); Expr.Cast(Value, type).Compile(ctx, true); gen.EmitCall(method); } } catch (KeyNotFoundException) { Error(CompilerMessages.VariableNotFound, Identifier); } }
protected override Type resolve(Context ctx, bool mustReturn) { if (Identifier == "_") error(CompilerMessages.UnderscoreNameUsed); var nameInfo = Local ?? ctx.Scope.FindLocal(Identifier); if (nameInfo != null) { if (nameInfo.IsImmutable && !IsInitialization) error(CompilerMessages.IdentifierIsConstant, Identifier); } else { try { _Property = ctx.ResolveGlobalProperty(Identifier); if (!_Property.HasSetter) error(CompilerMessages.GlobalPropertyNoSetter, Identifier); } catch (KeyNotFoundException) { error(CompilerMessages.VariableNotFound, Identifier); } } var destType = nameInfo != null ? nameInfo.Type : _Property.PropertyType; ensureLambdaInferred(ctx, Value, destType); var exprType = Value.Resolve(ctx); ctx.CheckTypedExpression(Value, exprType, true); if (!destType.IsExtendablyAssignableFrom(exprType)) { error( nameInfo != null ? CompilerMessages.IdentifierTypeMismatch : CompilerMessages.GlobalPropertyTypeMismatch, exprType, destType ); } return base.resolve(ctx, mustReturn); }
protected override Type resolveExpressionType(Context ctx, bool mustReturn = true) { var local = LocalName ?? ctx.CurrentScope.FindName(Identifier); if (local != null) { // only local constants are cached // because mutable variables could be closured later on if (local.IsConstant && local.IsImmutable && ctx.Options.UnrollConstants) m_LocalConstant = local; return local.Type; } try { var methods = ctx.MainType.ResolveMethodGroup(Identifier); if (methods.Length > 1) Error(CompilerMessages.FunctionInvocationAmbiguous, Identifier); m_Method = methods[0]; return FunctionalHelper.CreateFuncType(m_Method.ReturnType, m_Method.GetArgumentTypes(ctx)); } catch (KeyNotFoundException) { } try { m_Property = ctx.ResolveGlobalProperty(Identifier); return m_Property.PropertyType; } catch (KeyNotFoundException) { Error(CompilerMessages.IdentifierNotFound, Identifier); } return typeof (Unit); }