Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I want to make a simple, proof-of-concept application (REPL) that takes a number and then processes commands on that number.

Example: I start with 1. Then I write "add 2", it gives me 3. Then I write "multiply 7", it gives me 21. Then I want to know if it is prime, so I write "is prime" (on the current number - 21), it gives me false. "is odd" would give me true. And so on.

Now, for a simple application with few commands, even a simple switch would do for processing the commands. But if I want extensibility, how would I need to implement the functionality? Do I use the command pattern? Do I build a simple parser/interpreter for the language? What if I want more complex commands, like "multiply 5 until >200" ? What would be an easy way to extend it (add new commands) without recompiling?

Edit: to clarify a few things, my end goal would not be to make something similar to WolframAlpha, but rather a list (of numbers) processor. But I want to start slowly at first (on single numbers).

I'm having in mind something similar to the way one would use Haskell to process lists, but a very simple version. I'm wondering if something like the command pattern (or equivalent) would suffice, or if I have to make a new mini-language and a parser for it to achieve my goals?

Edit2: Thanks for all the responses, all have been very helpful to me, but Emmad Kareem's helped me the most, so I'll chose it as the answer. Thanks again!

share|improve this question
2  
I don't get the downvotes. Please state your reason so I can better formulate my question next time. –  Nini Michaels Nov 7 '12 at 11:24
2  
I really like this question. Looking forward to see what designs people suggest. Are you specifically looking for object oriented design (you mention command pattern, which is an OO pattern)? –  Bjarke Freund-Hansen Nov 7 '12 at 11:39
    
thank you :) yes, I would prefer OOP, but I won't mind if other methods are suggested! –  Nini Michaels Nov 7 '12 at 11:42
2  
It seems an implementation of Reverse Polish Notation, a very cool programming subject! –  ADC Nov 7 '12 at 12:00
1  
You are probably falling foul of the book clause from What kind of questions should I not ask here? in the FAQ, i.e. If you can imagine an entire book that answers your question, you’re asking too much. –  Mark Booth Nov 7 '12 at 13:57
show 3 more comments

4 Answers 4

up vote 5 down vote accepted

This sounds like an interpreter. It looks like you are worried about the implementation more than the detailed functionality (I am only guessing here). This project if extended is not a trivial task. Make sure you study the scope clearly as this requires engineering approach and not an ad-hoc development approach to get a reliable product rather than a product with 1000 patches that works sometimes only.

Decide on a syntax and be ready to parse it and perform the necessary syntax checks. This link may help you with this:Create your own parser.

Take a look at: this topic as it touches on different aspects of the work, also there are good links that may help you (specially the answer by RMK).:Creating a Language interpreter. You may want to see an example of a nice looking project that is somewhat similar at: Ultimate Programmable Scientific Calculator. You can find source code and working program for a command line C# interpreter here Command-Line-Implementation-of-C#-Made-for-Teaching. Using the compiler to do the complex tasks for you like parsing and variable typing, etc. may be a clever way to escape the complexities of writing all this yourself. Also, there is the Mono option which provides a charp shell feature that you may want to take a look at: CsharpRepl.

share|improve this answer
    
Thanks, your links are really helpful! So I guess an interpreter would be the best choice if I want to extend it easily. –  Nini Michaels Nov 7 '12 at 14:00
    
Thank you for the feedback, I guess starting with the link to the CodeProject may be a good idea. –  Emmad Kareem Nov 7 '12 at 16:12
add comment

Unless you're specifically interested in writing the actual parser for yourself, I'd suggest having a look at one of the parser generator frameworks. For C you have YACC or Bison, but there should be other alternatives for other languages if you prefer.

These takes away the complexities of parsing complex grammars and lets you concentrate on the task you want to do. Of course this may be overkill for the grammar you suggest in the question, but since you mention having the option of expanding to a more complex grammar later, it's at least worth getting some inspiration from these frameworks.

share|improve this answer
1  
The problem with most parser generators is that their artifacts are static, and don't lend themselves easily to extension. I think OP would be better served with something more like a rules engine, where the "rules" (keywords and syntax) are stored in a flexible data structure and evaluated after each input. –  TMN Nov 7 '12 at 14:58
add comment

What you are describing is very close to a stack language.

For instance in Factor what you describe would be done like

1
2 +
7 *
even? not

Or you could define your own words and then use them, like

: add ( x y -- sum ) + ;
: multiply ( x y -- product ) * ;
: odd? ( n -- ? ) even? not ;

With these definitions the above example becomes

1
2 add
7 multiply
odd?

Usually stack languages are trivial to parse because they use single words that are space separated. I suggest you have a look at Factor - it may be eaxctly what you want. It should be easy to define the words that do the processing you need.

EDIT: If you actually want to design a similar language, I suggest that you play with one of them anyway. Parsing a stack language is trivial - you split on blank spaces, and a naive implementation of processing is easy: you just need to take care of what happens on a stack.

share|improve this answer
    
This sounds pretty easy, and a good place to start. Thanks! –  Nini Michaels Nov 7 '12 at 17:53
add comment

But if I want extensibility, how would I need to implement the functionality?

You shouldn't. Extensibility creates a whole lot of complexity for very little gain. That said, you'll need to provide a hook into the existing state. A way to see the state, modify the state, and provide a mechanism to return other results (print to screen). You'll need a way for the core code to discover modules, load them, and dispatch commands to them.

Do I use the command pattern?

You can, but it's likely not appropriate.

You're not going to take the entire input and send it off for processing, but instead parse the input, dispatch to the correct handler and let it do its work. The command doesn't vary in that communication; so no command pattern.

Do I build a simple parser/interpreter for the language?

You'll need something to handle breaking the input into tokens. For an extensible solution, you probably won't do much more. For a well-defined solution, having a full parse tree will provide better performance, error handling, and debug-ability.

but rather a list (of numbers) processor

Then perhaps you should look into the LISt Processing language. The juxtaposition of code and data should fit in well with what you describe.

share|improve this answer
    
Thank you for the suggestions. As for LISP, I am familiar with it, and even more familiar with Haskell, which inspired me with this idea. However, even though I may be reinventing the wheel a bit, I want to get my hands dirty with processing commands and interpreting them. So it also has an educational purpose besides the actual "list processing" :) –  Nini Michaels Nov 7 '12 at 17:56
    
@NiniMichaels certainly, but as far as a design for extensibility goes, using lisp's organization/chaining of code/data isn't a bad option. –  Telastyn Nov 7 '12 at 18:14
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.