コード例 #1
0
ファイル: ParseCode.cs プロジェクト: ushim/PascalCompile
    /// <summary>
    /// Инициализирует переменную
    /// </summary>
    /// <param name="name">Имя переменной</param>
    /// <param name="type">Тип переменной</param>
    /// <param name="add_to_enviroment">Флаг, указывающий на то, стоит ли добавлять переменную в окружение</param>
    /// <returns>Созданную переменную</returns>
    private Variable InitVariable(string name, string type)
    {
        if (name == null)
        {
            name = "DYNAMIC";
        }

        type = GetRealType(FindType(type).Trim());
        bool pointer = (type.StartsWith("^")) ? true : false;
        if (pointer)
        {
            type = type.Remove(0, 1);
            Pointer p = new Pointer(name, type);
            if (name != "")
                env.Add(p, name);
            return p;
        }
        else
        {
            if (type.StartsWith("record") && type.EndsWith("end"))
            {
                string var_type = type.Remove(0, 6)
                    .Remove(type.Length - 9);
                var_type = var_type.Trim();
                TypeStruct[] tmp = GetTypeStructFromField(var_type);
                string[] names = new string[tmp.Length];
                Record r = new Record(name);
                r.type = type;
                for (int i = 0; i < names.Length; i++)
                    names[i] = tmp[i].name;
                r.SetFields(names);
                for (int i = 0; i < names.Length; i++)
                {
                    Variable v = InitVariable("", tmp[i].type);
                    r.SetVariable(v, names[i]);
                }
                if (name != "")
                    env.Add(r, name);
                return r;
            }
            else if (type.StartsWith("array"))
            {
                Match m;
                if ((m = Regexs.Match(type, Regs.ArrayClassic)).Success)
                {
                    object start = null;
                    if (!env.TryCalculate(m.Groups["from"].Value, out start))
                        throw new Exception(m.Groups["from"].Value + " не может быть начальным индексом массива");
                    object end = null;
                    if (!env.TryCalculate(m.Groups["to"].Value, out end))
                        throw new Exception(m.Groups["to"].Value + " не может быть конечным индексом массива");
                    if (start.GetType().Name != end.GetType().Name)
                        throw new Exception("Тип начального и конечного индекса массива должны совпадать");
                    if (start == null)
                        throw new Exception("Индекс массива не распознан, возможно вы использовали недопустимое выражение");
                    int len = 0;
                    if (start.GetType().Name == "Double")
                    {
                        if ((double)start >= (double)end)
                            throw new Exception("Начальны индекс не может быть больше или равен конечному");
                        else if ((int)(double)end != (double)end || (int)(double)start != (double)start)
                            throw new Exception("Индекс не может быть вещественным числом");
                        else
                            len = (int)(double)end - (int)(double)start + 1;
                    }
                    else if (start.GetType().Name == "Boolean")
                    {
                        if ((bool)start == true || (bool)end == false)
                            throw new Exception("Начальны индекс не может быть больше или равен конечному");
                        else
                               len = 2;
                    }

                    Massiv mas = new Massiv(name);
                    string[] names = new string[len];
                    if (start.GetType().Name == "Boolean")
                    {
                        names[0] = "false";
                        names[1] = "true";
                    }
                    else
                        for (int i = 0; i < len; i++)
                            names[i] = (i + (int)(double)start).ToString();
                    mas.SetFields(names);
                    for (int i = 0; i < len; i++)
                    {
                        Variable v = InitVariable("", m.Groups["base_type"].Value);
                        mas.SetVariable(v, names[i]);
                    }
                    mas.type = type;
                    if (name != "")
                        env.Add(mas, name);
                    return mas;
                }
                return new NullVariable();
            }
            else if (type == "real")
            {
                Real r = new Real(name);
                if (name != "")
                    env.Add(r, name);
                return r;
            }
            else if (type == "integer")
            {
                Integer i = new Integer(name);
                if (name != "")
                    env.Add(i, name);
                return i;
            }
            else if (type == "boolean")
            {
                Boolean b = new Boolean(name);
                if (name != "")
                    env.Add(b, name);
                return b;
            }
            else if (type == "char")
            {
                Char c = new Char(name);
                if (name != "")
                    env.Add(c, name);
                return c;
            }
            else
            {
                Variable v = new Variable(name);
                if (name != "")
                    env.Add(v, name);
                return v;
            }
        }
    }