예제 #1
0
파일: Exprs.cs 프로젝트: ZiCog/HomeSpun
        Expr SubscriptExprs(Expr[] indexExprs, Expr[] dimExprs)
        {
            if (indexExprs == null)
                return null;
            if (indexExprs.Length == 1)
                return indexExprs[0];		// special case: single index is always OK

            if (indexExprs.Length < dimExprs.Length)
            {
                throw new ParseException("Not enough subscripts", indexExprs[indexExprs.Length - 1].Token);
            }
            else if (indexExprs.Length > dimExprs.Length)
            {
                throw new ParseException("Too many subscripts", indexExprs[dimExprs.Length].Token);
            }
            else // indexExprs.Length == dimExprs.Length
            {
                /*        |                   |                  |
                        ind[0]  dim[1] * ind[1] +  dim[2] * ind[2] +   dim[3] * ind[3] +
                     */
                Expr indexExpr = indexExprs[0];
                for (int i = 1; i < indexExprs.Length; ++i)
                {
                    int dim = Expr.EvaluateIntConstant(dimExprs[i]);
                    indexExpr = new BinaryExpr(null, 0xf4, indexExpr, new IntExpr(null, dim));	// mul
                    indexExpr = new BinaryExpr(null, 0xec, indexExpr, indexExprs[i]);				// add
                }
                return indexExpr;
            }
        }
예제 #2
0
파일: Tdop.cs 프로젝트: ZiCog/HomeSpun
        public override bool Std(out Stmt s)
        {
            s = null;
            if (this.Column != 0)
                throw new ParseException("CON must be in 1st column", this);
            Tokenizer.Advance();	// past "CON"
            if (Tokenizer.Current.Text == "(eol)")
                Tokenizer.Advance("(eol)");

            Expr conOrgExpr = new IntExpr(new SimpleToken(Tokenizer, SimpleTokenType.IntLiteral, "0", 0, 0, 0), 0);

            while (true)
            {
                if (Tokenizer.Current.Text == "#")
                {
                    Tokenizer.Advance("#");
                    conOrgExpr = ParseExpression(Tokenizer, 13);
                }
                else if (Tokenizer.Current is IdToken)
                {
                    IdToken constantName = Tokenizer.GetToken() as IdToken;
                    if (Tokenizer.Current.Text == "=")
                    {
                        Tokenizer.Advance("=");
                        SymbolTable.AddConSymbol(constantName, ParseExpression(Tokenizer, 13));
                    }
                    else
                    {
                        SymbolTable.AddConSymbol(constantName, conOrgExpr);
                        if (Tokenizer.Current.Text == "[")
                        {
                            Tokenizer.Advance("[");
                            Expr incrExpr = ParseExpression(Tokenizer, 13);
                            Tokenizer.Advance("]");

                            conOrgExpr = new BinaryExpr(
                                new SimpleToken(Tokenizer, SimpleTokenType.Op, "+", 0, 0),
                                666, // fake opcode
                                conOrgExpr, incrExpr);
                        }
                        else
                        {
                            Expr incrExpr = new IntExpr(new SimpleToken(Tokenizer, SimpleTokenType.IntLiteral, "(1)", 0, 0, 1), 1);

                            conOrgExpr = new BinaryExpr(
                                new SimpleToken(Tokenizer, SimpleTokenType.Op, "+", 0, 0),
                                666, // fake opcode
                                conOrgExpr, incrExpr);
                        }
                    }
                }
                else
                    break;
                if (Tokenizer.Current.Text == ",")
                    Tokenizer.Advance(",");
                else
                    Tokenizer.Advance("(eol)");
            }
            return true;
        }
예제 #3
0
파일: Exprs.cs 프로젝트: ZiCog/HomeSpun
        public void Visit(BinaryExpr e)
        {
            FloInt r1 = Expr.EvaluateConstant(e.Operand1, insideDat);
            FloInt r2 = Expr.EvaluateConstant(e.Operand2, insideDat);

            if (r1.IsInt)
            {
                if (!r2.IsInt)
                    throw new ParseException("Can't mix int and floating-point", e.Token);
                int i1 = r1.IntValue;
                int i2 = r2.IntValue;
                switch (e.Token.Text.ToUpper())
                {
                    case "->": result = new FloInt(Ror(i1, i2)); break;
                    case "<-": result = new FloInt(Rol(i1, i2)); break;
                    case ">>": result = new FloInt(Shr(i1, i2)); break;
                    case "<<": result = new FloInt(i1 << i2); break;
                    case "~>": result = new FloInt(Sar(i1, i2)); break;
                    case "><": result = new FloInt(Rev(i1, i2)); break;
                    case "&": result = new FloInt(i1 & i2); break;
                    case "|": result = new FloInt(i1 | i2); break;
                    case "^": result = new FloInt(i1 ^ i2); break;
                    case "*": result = new FloInt(i1 * i2); break;
                    case "**": result = new FloInt((int)(((long)i1 * (long)i2) >> 32)); break;
                    case "/": result = new FloInt(i1 / i2); break;
                    case "//": result = new FloInt(i1 % i2); break;
                    case "+": result = new FloInt(i1 + i2); break;
                    case "-": result = new FloInt(i1 - i2); break;
                    case "#>": result = new FloInt(i1 > i2 ? i1 : i2); break;
                    case "<#": result = new FloInt(i1 > i2 ? i2 : i1); break;
                    case "<": result = new FloInt(i1 < i2 ? -1 : 0); break;
                    case ">": result = new FloInt(i1 > i2 ? -1 : 0); break;
                    case "<>": result = new FloInt(i1 != i2 ? -1 : 0); break;
                    case "==": result = new FloInt(i1 == i2 ? -1 : 0); break;
                    case "=<": result = new FloInt(i1 <= i2 ? -1 : 0); break;
                    case "=>": result = new FloInt(i1 >= i2 ? -1 : 0); break;
                    case "AND": result = new FloInt((i1 != 0) && (i2 != 0) ? -1 : 0); break;
                    case "OR": result = new FloInt((i1 != 0) || (i2 != 0) ? -1 : 0); break;
                    default: throw new ParseException("Bad operator in constant expression: " + e.Token.Text, e.Token);
                }
            }
            else	// r1 is float
            {
                if (r2.IsInt)
                    throw new ParseException("Can't mix int and floating-point", e.Token);
                float f1 = r1.FloatValue;
                float f2 = r2.FloatValue;
                switch (e.Token.Text.ToUpper())
                {
                    case "*": result = new FloInt(f1 * f2); break;
                    case "/": result = new FloInt(f1 / f2); break;
                    case "+": result = new FloInt(f1 + f2); break;
                    case "-": result = new FloInt(f1 - f2); break;
                    case "#>": result = new FloInt(f1 > f2 ? f1 : f2); break;
                    case "<#": result = new FloInt(f1 > f2 ? f2 : f1); break;
                    case "<": result = new FloInt(f1 < f2 ? 1.0f : 0.0f); break;
                    case ">": result = new FloInt(f1 > f2 ? 1.0f : 0.0f); break;
                    case "<>": result = new FloInt(f1 != f2 ? 1.0f : 0.0f); break;
                    case "==": result = new FloInt(f1 == f2 ? 1.0f : 0.0f); break;
                    case "=<": result = new FloInt(f1 <= f2 ? 1.0f : 0.0f); break;
                    case "=>": result = new FloInt(f1 >= f2 ? 1.0f : 0.0f); break;
                    case "AND": result = new FloInt((f1 != 0.0f) && (f2 != 0.0f) ? 1.0f : 0.0f); break;
                    case "OR": result = new FloInt((f1 != 0.0f) || (f2 != 0.0f) ? 1.0f : 0.0f); break;
                    default: throw new ParseException("Bad operator in constant expression: " + e.Token.Text, e.Token);
                }
            }
        }