如何将基于文本的编程代码(存储在DB中)转换为实际的编程代码?

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?

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?

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/

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

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.

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/