Example #1
0
        /// <summary>
        /// Process func and changes appropriate S Expressions to cond expressions.
        /// </summary>
        /// <param name="func"></param>
        /// <returns></returns>
        private static IParsedValue ProcessConds(IParsedValue func)
        {
            if (func.ParsedValueType != ParsedValuesTypes.PARSEDSEXPR) return func;

            if ((func as ParsedSExpr).Members[0].ParsedValueType != ParsedValuesTypes.PARSEDIDENTIFIER)
                throw new Exception("Something strange happened during cond conversion.\n");
            else if (((func as ParsedSExpr).Members[0] as ParsedIdentifier).Name != "cond")
            {
                List<IParsedValue> newMembers = new List<IParsedValue>();
                foreach (var i in (func as ParsedSExpr).Members)
                {
                    newMembers.Add(ProcessConds(i));
                }
                (func as ParsedSExpr).Members = newMembers;
                return func;
            }
            else
            {
                ParsedCondExpression pce = new ParsedCondExpression();
                var mem = (func as ParsedSExpr).Members;
                for (int i = 1; i < mem.Count; i++)
                {
                    if (mem[i].ParsedValueType != ParsedValuesTypes.PARSEDSEXPR) throw new Exception("Incorrect cond clause.");
                    var clause = mem[i] as ParsedSExpr;
                    if (clause.Members.Count != 2) throw new Exception("Incorrect cond clause.");
                    pce.Clauses.Add(new CondClause { Condition = ProcessConds(clause.Members[0]), Result = ProcessConds(clause.Members[1]) });
                }
                return pce;
            }
        }
        /// <summary>
        /// Rercursive function, valdating function call.
        /// Raises Exception in case of failure.
        /// </summary>
        /// <param name="sexpr">Should contain: FuncName, Params.</param>
        private void ValidateFuncCall(IParsedValue call)
        {
            if (call.ParsedValueType == ParsedValuesTypes.PARSEDSEXPR)
            {
                var sexpr = call as ParsedSExpr;
                Function func = FindFunction(sexpr);
                List<VarType> callArgList = GetFuncCallArguments(sexpr);
                List<VarType> funcArgList = func.Arguments.Values.ToList();

                if (callArgList.Count != funcArgList.Count)
                    throw new Exception("SA: Wrong arguments list length at " + func.Name + " function call!");

                for (int i = 0; i < callArgList.Count; i++)
                    if (!IsTypesCompatible(funcArgList[i], callArgList[i]))
                        throw new Exception("SA: Wrong arguments type at " + func.Name + " function call!");
            }
            else if (call.ParsedValueType == ParsedValuesTypes.PARSEDCOND)
            {
                var ccl = call as ParsedCondExpression;
                foreach (var cl in ccl.Clauses)
                {
                    ValidateFuncCall(cl.Condition);
                    ValidateFuncCall(cl.Result);
                }
            }
        }
        private VarType GetArgumentType(string arg, IParsedValue val)
        {
            VarType result = VarType.Any;
            if (val.ParsedValueType == ParsedValuesTypes.PARSEDSEXPR)
            {
                var pse = val as ParsedSExpr;
                List<IParsedValue> temp = new List<IParsedValue>(pse.Members);

                // get function
                Function calledFunc = FindFunction(pse);

                // remove function name
                temp.RemoveAt(0);

                // search in direct parameters
                foreach (var a in temp.Where(x => x.ParsedValueType == ParsedValuesTypes.PARSEDIDENTIFIER))
                {
                    // found our parameter
                    if ((a as ParsedIdentifier).Name == arg)
                    {
                        int idx = temp.IndexOf(a);
                        result = Sup(result, calledFunc.Arguments.ElementAt(idx).Value);
                    }
                }

                // search in function calls
                foreach (var fa in temp.Where(x => x.ParsedValueType == ParsedValuesTypes.PARSEDSEXPR ||x.ParsedValueType == ParsedValuesTypes.PARSEDCOND))
                {
                    result = Sup(result, GetArgumentType(arg, fa));
                }
            }
            else if (val.ParsedValueType == ParsedValuesTypes.PARSEDCOND)
            {
                var pse = val as ParsedCondExpression;
                foreach (var x in pse.Clauses)
                {
                    result = Sup(result, GetArgumentType(arg, x.Condition));
                    result = Sup(result, GetArgumentType(arg, x.Result));
                }
            }
            return result;
        }
 private VarType DeriveIPVRetType(Function context, IParsedValue ipv)
 {
     var Result = VarType.Nothing;
     switch (ipv.ParsedValueType)
     {
         case ParsedValuesTypes.PARSEDCHARCONST: return VarType.Char;
         case ParsedValuesTypes.PARSEDIDENTIFIER:
             var an = (ipv as ParsedIdentifier).Name;
             if (an == "nil" || an == "T") return VarType.Any;
             return context.Arguments[(ipv as ParsedIdentifier).Name];
         case ParsedValuesTypes.PARSEDINTEGERCONST: return VarType.Integer;
         case ParsedValuesTypes.PARSEDSTRINGCONST: return VarType.String;
         case ParsedValuesTypes.PARSEDCOND:
             foreach (var s in (ipv as ParsedCondExpression).Clauses)
                 Result = Inf(Result, DeriveIPVRetType(context, s.Result));
             return Result;
         case ParsedValuesTypes.PARSEDSEXPR:
             var se = ipv as ParsedSExpr;
             if ((se.Members[0] as ParsedIdentifier).Name == "if") // Crutch
               return Inf(Result, Inf(DeriveIPVRetType(context, se.Members[1]), DeriveIPVRetType(context, se.Members[1])));
             return FindFunction(ipv as ParsedSExpr).RetType;
         default: // Serious shit. You wont ever see that
             return VarType.Nothing;
     }
 }
Example #5
0
        /// <summary>
        /// Generates C code from a IParsedValue.
        /// </summary>
        /// <param name="pse"></param>
        /// <returns>Function C code.</returns>
        private string GenerateCCode(IParsedValue pse)
        {
            string result = "";

            switch(pse.ParsedValueType)
            {
                case ParsedValuesTypes.PARSEDSEXPR:
                    List<IParsedValue> temp = new List<IParsedValue>((pse as ParsedSExpr).Members);

                    if (temp[0].ParsedValueType != ParsedValuesTypes.PARSEDIDENTIFIER)
                        throw new Exception("CG.GenerateCCode: Not a function call!");

                    string calledFuncName = (temp[0] as ParsedIdentifier).Name;
                    temp.RemoveAt(0);

                    // standart function call
                    if (FuncDefs[calledFuncName].Body == null)
                    {
                        result += GenerateStandartCFunctionCall(calledFuncName, temp);
                    }
                    else
                    {
                        result += calledFuncName + "( ";

                        bool x = false;
                        foreach (var a in temp)
                        {
                            if (x) result += ", ";
                            x = true;
                            result += GenerateCCode(a);
                        }

                        result += ")";
                    }
                    break;
                case ParsedValuesTypes.PARSEDINTEGERCONST:
                    result += (pse as ParsedIntegerConst).Value.ToString();
                    break;
                case ParsedValuesTypes.PARSEDIDENTIFIER:
                    result += (pse as ParsedIdentifier).Name;
                    break;
                case ParsedValuesTypes.PARSEDCHARCONST:
                    result += "'" + (pse as ParsedCharConst).Value + "'";
                    break;
                case ParsedValuesTypes.PARSEDSTRINGCONST:
                    result += "\"" + (pse as ParsedStringConst).Value + "\"";
                    break;
                case ParsedValuesTypes.PARSEDCOND:
                    ParsedCondExpression cond = pse as ParsedCondExpression;

                    result += "{\n";

                    foreach (var cl in cond.Clauses)
                    {
                        result += "\n\t if (";

                        if (cl.Condition.ParsedValueType == ParsedValuesTypes.PARSEDCOND)
                            throw new Exception("CG.GenerateCCode: Cond is not accepted as cond condition!");

                        result += GenerateCCode(cl.Condition) + " )";

                        if (cl.Result.ParsedValueType == ParsedValuesTypes.PARSEDCOND)
                            result += GenerateCCode(cl.Result);
                        else
                            result += "\n return " + GenerateCCode(cl.Result) + ";\n";
                    }

                    result += "\n}";
                    break;
                default:
                    break;
            }

            return result;
        }