2

Ok, i have a need to store some simple programming code text in DB, & then my application will read these text & convert them into actual programming code.

A good example is sqlfiddle.com. This website allow you to put sql code into it website, u then click a button & u can see the table result of that sql code. Ofcourse sqlfiddle must store the Txt-based code that u input into its database.

Another example is w3schools.com. It allows user to submit html code & then users can see the result on the fly. Ex:http://www.w3schools.com/js/tryit.asp?filename=tryjs_events

In my case i just need to use some limited keywords such as (if, for, while, +, *, -, /...)

Ex, I have a table called OrderItem with 3 columns:

ItemID - Qantity -Cost
Item1 - 10 - 5 USD
Item2 - 12 - 2 USD
Item3 - 4 - 1 USD

I also have a table ProgrammingCode

ItemID - Code
Item1 - "if quantity > 2 then totalcost=10*5 USD else totalCost=10*4USD; return totalCost"
Item2 - "if time=9am then totalcost=12*2 USD else totalCost=12*1USD; return totalCost "

Note: since there are variety of calculating rules in the real world, the code should be able to depict the real world so If or loop & all arithmetic operators should be used.

This is my Pseudocodefunction but i don't think it works.

    public String covertCode(String textBasedCode){
        String[] eachWord=textBasedCode.split(" ");
        if(eachWord[0].equals("if")){
             //do a lot of checking. how to let the program to know this?
             if(eachWord[2]>2{
                 return 10*5;
             }
             else{
                 return 10*4;
              }
         }
      }

I used java in this example, but u can use C++, C# php or any programming language you want. I just want to know the logic.

So, How to convert Text-based programming code (stored in DB) into actual programming code?

Tum
  • 3,614
  • 5
  • 38
  • 63
  • Google writing a scripting engine which is what you are trying to achieve by the looks of it. – Belogix Aug 15 '13 at 08:09
  • Where is `javascript` and `python` tags? – Soner Gönül Aug 15 '13 at 08:12
  • i just want some very basic codes (if, for, while loop, +, -) i don't need a whole compiler – Tum Aug 15 '13 at 08:14
  • Creating a language interpreter. http://stackoverflow.com/questions/2413565/creating-a-language-interpreter – Jeroen van Langen Aug 15 '13 at 08:15
  • Your "mini language" looks like SQL to me. And it seemingly operates on data. Why not just write a web site which would take an SQL query from the user and run it against a database, returning the results? Much like `phpMyAdmin` already does in its interface? – kostix Aug 15 '13 at 09:26
  • a lot of if then statement in sql query is not user friendly. I want the user to be able to put the formula & they don;t need to learn sql. Also it could be threadt if using improperly. I think i found an elegant solution – Tum Aug 15 '13 at 11:24

5 Answers5

2

You could create your own mini interpreter which will interpret the code. It shouldn't take a very long time since you want it be limited.

But since all it does is calculate values, I think you could just let them store the numbers and you do the math within your code following your rules. Most database come with plenty of functions builtin, so this can also be done from within the database.

I just don't see how "Text-based programming code" is different from "actual programming code".

So you can use the interpreter design pattern for this. There is probably other ways but this is my best guess. And you won't get code if that's what you looking for.

Touch
  • 1,481
  • 10
  • 19
  • i also think about Stored procedure in DB, we just need to create stored-procedures & then the progam just call its name – Tum Aug 15 '13 at 08:29
  • You want to use stored procedures? That could work too and save you sometime while you at it. (It's part of the database builtin stuff I'm talking about). Use them if you can. – Touch Aug 15 '13 at 08:36
1

You can use Microsoft.CSharp.CSharpCodeProvider to compile code on-the-fly. In particular, Check CompileAssemblyFromFile

Kurubaran
  • 8,696
  • 5
  • 43
  • 65
  • there no such thing in Java – Tum Aug 15 '13 at 08:25
  • @MinhHai, may [this](http://docs.oracle.com/javase/7/docs/api/javax/tools/JavaCompiler.html) be of help? Not exactly like what `Coder` suggested, but at least a sort of poor-man's solution. – kostix Aug 15 '13 at 09:28
  • i need it to return a vale. Also a whole Java interpreter for small application is not too elegant. – Tum Aug 15 '13 at 11:27
1

Check out the Roslyn project. It gives you the opportunity to use the compiler as a service to create plugins, code analyzers, etc.

http://msdn.microsoft.com/en-us/vstudio/hh500769.aspx

http://blog.filipekberg.se/2013/02/07/compilation-as-a-service-and-the-next-generation-plugins/

Balázs Szántó
  • 1,440
  • 3
  • 15
  • 29
0

The hard way is to interpret the code within the database, the easier way is to store c# code and runtime compile it with CodeDOM http://msdn.microsoft.com/en-us/library/y2k85ax6.aspx

Or take a look at Iron Python. http://ironpython.net/

Jeroen van Langen
  • 21,446
  • 3
  • 42
  • 57
  • I need the returned value from the code, the textbased code cannot stand independently – Tum Aug 15 '13 at 08:11
0

I think I found an elegant solution based on the suggestion of Interpreter Pattern that Touch suggested me. I didn't know Interpreter Pattern before but after reading it for 15 mins I could come up a cool solution. I never earned an accepted answer before so i hope my answer can earn it.

The logic is simple. We gotta use the "Reverse Polish Notation expressions" like:

a b +
a b c + -
a b + c a - -

& that is done. http://en.wikipedia.org/wiki/Interpreter_pattern

     interface Expression {
    public int interpret(Map<String,Expression> variables);
}

class Number implements Expression {
    private int number;
    public Number(int number)       { this.number = number; }
    public int interpret(Map<String,Expression> variables)  { return number; }
}

class Plus implements Expression {
    Expression leftOperand;
    Expression rightOperand;
    public Plus(Expression left, Expression right) { 
        leftOperand = left; 
        rightOperand = right;
    }

    public int interpret(Map<String,Expression> variables)  { 
        return leftOperand.interpret(variables) + rightOperand.interpret(variables);
    }
}

class Minus implements Expression {
    Expression leftOperand;
    Expression rightOperand;
    public Minus(Expression left, Expression right) { 
        leftOperand = left; 
        rightOperand = right;
    }

    public int interpret(Map<String,Expression> variables)  { 
        return leftOperand.interpret(variables) - rightOperand.interpret(variables);
    }
}
class Times implements Expression {
    Expression leftOperand;
    Expression rightOperand;
    public Times(Expression left, Expression right) { 
        leftOperand = left; 
        rightOperand = right;
    }

    public int interpret(Map<String,Expression> variables)  { 
        return leftOperand.interpret(variables) * rightOperand.interpret(variables);
    }
} 

class Division implements Expression {
    Expression leftOperand;
    Expression rightOperand;
    public Division(Expression left, Expression right) { 
        leftOperand = left; 
        rightOperand = right;
    }

    public int interpret(Map<String,Expression> variables)  { 
        return leftOperand.interpret(variables) / rightOperand.interpret(variables);
    }
}

class IfThen implements Expression {
    Expression leftOperand;
    Expression rightOperand;
    public IfThen(Expression left, Expression right) { 
        leftOperand = left; 
        rightOperand = right;
    }

    public int interpret(Map<String,Expression> variables)  { 
        return (leftOperand.interpret(variables)==1) ? rightOperand.interpret(variables) : 0;
    }
}

class GreaterThan implements Expression {
    Expression leftOperand;
    Expression rightOperand;
    public GreaterThan(Expression left, Expression right) { 
        leftOperand = left; 
        rightOperand = right;
    }

    public int interpret(Map<String,Expression> variables)  { 
        return (leftOperand.interpret(variables) > rightOperand.interpret(variables)) ? 1 : 0;
    }
}

class GreaterThanOrEqual implements Expression {
    Expression leftOperand;
    Expression rightOperand;
    public GreaterThanOrEqual(Expression left, Expression right) { 
        leftOperand = left; 
        rightOperand = right;
    }

    public int interpret(Map<String,Expression> variables)  { 
        return (leftOperand.interpret(variables) >= rightOperand.interpret(variables)) ? 1 : 0;
    }
}
class LessThan implements Expression {
    Expression leftOperand;
    Expression rightOperand;
    public LessThan(Expression left, Expression right) { 
        leftOperand = left; 
        rightOperand = right;
    }

    public int interpret(Map<String,Expression> variables)  { 
        return (leftOperand.interpret(variables) < rightOperand.interpret(variables)) ? 1 : 0;
    }
}

class LessThanOrEqual implements Expression {
    Expression leftOperand;
    Expression rightOperand;
    public LessThanOrEqual(Expression left, Expression right) { 
        leftOperand = left; 
        rightOperand = right;
    }

    public int interpret(Map<String,Expression> variables)  { 
        return (leftOperand.interpret(variables) <= rightOperand.interpret(variables)) ? 1 : 0;
    }
}

class Equal implements Expression {
    Expression leftOperand;
    Expression rightOperand;
    public Equal(Expression left, Expression right) { 
        leftOperand = left; 
        rightOperand = right;
    }

    public int interpret(Map<String,Expression> variables)  { 
        return (leftOperand.interpret(variables) == rightOperand.interpret(variables)) ? 1 : 0;
    }
}
class Variable implements Expression {
    private String name;
    public Variable(String name)       { this.name = name; }
    public int interpret(Map<String,Expression> variables)  { 
        if(null==variables.get(name)) return 0; //Either return new Number(0).
        return variables.get(name).interpret(variables); 
    }
}
class Evaluator implements Expression {
    private Expression syntaxTree;

    public Evaluator(String expression) {
        Stack<Expression> expressionStack = new Stack<Expression>();
        for (String token : expression.split(" ")) {
            if  (token.equals("+")) {
                Expression subExpression = new Plus(expressionStack.pop(), expressionStack.pop());
                expressionStack.push( subExpression );
            }
            else if (token.equals("-")) {
                // it's necessary remove first the right operand from the stack
                Expression right = expressionStack.pop();
                // ..and after the left one
                Expression left = expressionStack.pop();
                Expression subExpression = new Minus(left, right);
                expressionStack.push( subExpression );
            }
            else if  (token.equals("*")) {
                Expression subExpression = new Times(expressionStack.pop(), expressionStack.pop());
                expressionStack.push( subExpression );
            }
            else if  (token.equals("/")) {
                // it's necessary remove first the right operand from the stack
                Expression right = expressionStack.pop();
                // ..and after the left one
                Expression left = expressionStack.pop();
                Expression subExpression = new Division(left, right);
                expressionStack.push( subExpression );
            }
            else if  (token.equals("if-then")) {
                // it's necessary remove first the right operand from the stack
                Expression right = expressionStack.pop();
                // ..and after the left one
                Expression left = expressionStack.pop();
                Expression subExpression = new IfThen(left, right);
                expressionStack.push( subExpression );
            }
            else if  (token.equals(">")) {
                // it's necessary remove first the right operand from the stack
                Expression right = expressionStack.pop();
                // ..and after the left one
                Expression left = expressionStack.pop();
                Expression subExpression = new GreaterThan(left, right);
                expressionStack.push( subExpression );
            }
            else if  (token.equals(">=")) {
                // it's necessary remove first the right operand from the stack
                Expression right = expressionStack.pop();
                // ..and after the left one
                Expression left = expressionStack.pop();
                Expression subExpression = new GreaterThanOrEqual(left, right);
                expressionStack.push( subExpression );
            }
            else if  (token.equals("<")) {
                // it's necessary remove first the right operand from the stack
                Expression right = expressionStack.pop();
                // ..and after the left one
                Expression left = expressionStack.pop();
                Expression subExpression = new LessThan(left, right);
                expressionStack.push( subExpression );
            }
            else if  (token.equals("<=")) {
                // it's necessary remove first the right operand from the stack
                Expression right = expressionStack.pop();
                // ..and after the left one
                Expression left = expressionStack.pop();
                Expression subExpression = new LessThanOrEqual(left, right);
                expressionStack.push( subExpression );
            }
            else if  (token.equals("==")) {
                // it's necessary remove first the right operand from the stack
                Expression right = expressionStack.pop();
                // ..and after the left one
                Expression left = expressionStack.pop();
                Expression subExpression = new Equal(left, right);
                expressionStack.push( subExpression );
            }
            else                        
                expressionStack.push( new Variable(token) );
        }
        syntaxTree = expressionStack.pop();
    }

    public int interpret(Map<String,Expression> context) {
        return syntaxTree.interpret(context);
    }
}

& that's it. To call the the converting method we just need this. See this simple code:

    String expression = "w x == z if-then";
                //String expression = "w x - z +";
                Evaluator sentence = new Evaluator(expression);
                Map<String,Expression> variables = new HashMap<String,Expression>();
                variables.put("w", new Number(10));
                variables.put("x", new Number(5));
                variables.put("z", new Number(42));
                int result = sentence.interpret(variables);
                System.out.println(result);

& that done. But it has limit that it doesn't have a loop, but if then is quite enough for me.

Am i doing correctly?

Tum
  • 3,614
  • 5
  • 38
  • 63
  • Only you can accept an answer but unfortunately you don't get rep for your own answer if you asked the question. [Accepting own answer](http://blog.stackoverflow.com/2009/01/accept-your-own-answers/) I'm not much of a java guy but as long as it does the trick. I'm sure you can work around the loop problem quiet easily. – Touch Aug 15 '13 at 17:02
  • the problem is that "for loop" use variable. + - * / or if-then use fixed value then they r easy, but the loop is not fixed so it could be hard. – Tum Aug 15 '13 at 20:59