//Returns a variable from a local scope marked with NoInit flag //If such variable couldn't be found returns -1 private ScopeVar GetNoInitVariable(ElaEquation s, out string name) { ScopeVar var; name = s.Left.GetName(); if (s.IsFunction()) { name = s.GetFunctionName(); } if (CurrentScope.Locals.TryGetValue(name, out var)) { //If it doesn't have a NoInit flag we are not good if ((var.Flags & ElaVariableFlags.NoInit) != ElaVariableFlags.NoInit) { return(ScopeVar.Empty); } else { var.Address = 0 | var.Address << 8; //Aligning it to local scope return(var); } } return(ScopeVar.Empty); }
//Adds a variable with NoInit flag to the current scope //This method also calculates additional flags and metadata for variables. //If a given binding if defined by pattern matching then all variables from //patterns are traversed using AddPatternVariable method. private bool AddNoInitVariable(ElaEquation exp) { var flags = exp.VariableFlags | ElaVariableFlags.NoInit; //This binding is not defined by PM if (exp.IsFunction()) { var name = exp.GetFunctionName(); if (name == null || Char.IsUpper(name[0])) { AddError(ElaCompilerError.InvalidFunctionDeclaration, exp, FormatNode(exp.Left)); return(false); } AddVariable(name, exp.Left, flags | ElaVariableFlags.Function, exp.GetArgumentNumber()); } else if (exp.Left.Type == ElaNodeType.NameReference && !((ElaNameReference)exp.Left).Uppercase) { var data = -1; if (exp.Right.Type == ElaNodeType.Builtin) { //Adding required hints for a built-in data = (Int32)((ElaBuiltin)exp.Right).Kind; flags |= ElaVariableFlags.Builtin; } else if (exp.Right.Type == ElaNodeType.Lambda) { var fun = (ElaLambda)exp.Right; flags |= ElaVariableFlags.Function; data = fun.GetParameterCount(); } else if (exp.Right.IsLiteral()) { flags |= ElaVariableFlags.ObjectLiteral; } AddVariable(exp.Left.GetName(), exp, flags, data); } else { AddPatternVariables(exp.Left); } return(true); }