3

I have googled about trying to find a simple example of Haskell being used to define a simple language but to no avail.

I did find this post on stackoverflow giving a similar example, but when i implemented it, it didn't appear to work:

Haskell - How to best to represent a programming language's grammar?

an example expression in this language would be:

if true then x else (if false then y else true) Your Haskell data type would look something like this:

data Expr = Var String
          | Lit Bool
          | If Expr Expr Expr

however, when i entered if true then x else (if false then y else true) into the console as input, it complained about "x" not being interpretable. It also didn't like true and false.

EDIT: I did derive "show" also, at the end

Community
  • 1
  • 1
user997112
  • 29,025
  • 43
  • 182
  • 361

6 Answers6

4

There are a couple of common steps to creating a programming language (there are others, of course):

  • parse the program text into a syntax tree
  • walk the syntax tree, doing something with it (interpreting, compiling, collecting statistics)

The data Expr you've shown would be part of a syntax tree. The if true then ... is program text. You need some way to get from text to tree: you need a parser.

Or, you can use Haskell as your parser, and write the syntax tree as Haskell code:

If True "it's true!" (If False "uh-oh" "it's false")
Matt Fenwick
  • 48,199
  • 22
  • 128
  • 192
  • Ok lets keep this simple, what if my programming language was: the word "desk" has to always follow the word "chair" so "chair desk" should be allowed but "desk chair" shouldnt. how would i declare this in haskell? – user997112 Oct 27 '11 at 16:07
  • @user997112: first, you would have a parser that would only succeed on the input string "chair desk", and fail for all other inputs. Then, you would have a Haskell datatype, something like: `data SimpleTree = DeskChair`. The parser would return `DeskChair` on success. – Matt Fenwick Oct 27 '11 at 18:09
4

Parsec has extensive programming-language-focused tools. So that's a great place to get started.

It may take some time to wrap your head around the distinction between two things:

  • Your programming language as text saved in a file.

  • The representation, in Haskell, of that language.

That's why you need the Lit True and not just true. true is the text in your programming language. Lit True is the Haskell representation. Linking the two is what a parser is for.

To answer another of your questions in comments, a basic solution of the "chair desk" problem is this:

import Text.Parsec

data ProgrammableFurniture = ChairDesk 
                           | CouchCoffeeTable

--a parser for the text "chair desk"
chairDesk = do string "chair"
               char ' '
               string "desk" <?> "Chair must be followed by desk!"
               return ChairDesk
Zopa
  • 668
  • 4
  • 7
3

If you want to represent if true then x else (if false then y else true) in your little language, you need to use the following expression:

If (Lit True) (Var "x") (If (Lit False) (Var "y") (Lit True))

If, as you say, you derived Show this will also show exactly as entered.

I'm not sure what more you want to do! Possible further things to try are:

  • Writing an evaluation function.
  • Writing your own Show instance to get the printed representation to look nicer.
  • Writing a parser for this little language.
yatima2975
  • 6,580
  • 21
  • 42
  • Hi, I basically want to create a set of rules so i can define a basic programming language – user997112 Oct 27 '11 at 15:27
  • But surely the point is you would parse in a text file of an actual programming language, so you shouldnt need Lit True? If this was a Java compiler written in haskell, the .java file wouldn't include Lit True, it would just say True (or even 'true') ? – user997112 Oct 27 '11 at 15:35
0

Along the same vein as yatima2975's answer, you can simply derive Read.

data Expr = Var String
          | Lit Bool
          | If Expr Expr Expr
          deriving (Read, Show)

Then if you use the read function on a String with the same format as yatima illustrated, it can produce an Expr. Notice I had to escape the " around the inner strings.

ghci> read "If (Lit True) (Var \"x\") (If (Lit False) (Var \"y\") (Lit True))" :: Expr
If (Lit True) (Var "x") (If (Lit False) (Var "y") (Lit True))

This is simpler than defining your own Read instance, but you could do that, too.

Dan Burton
  • 53,238
  • 27
  • 117
  • 198
-1

Unfortunately, language syntax and parsing do not rise to the level of defining a programming language. Defining the semantics of the language is the most important part and if well-defined (which it must be by definition to settle conformance issues of implementations of a language) goes the distance to improve implementation whether via interpreter or compiler.

While Haskell is a purely functional language there are criticisms regarding its lazy evaluation which introduces problems regarding reasoning about its performance.

Regarding Haskell's suitability for what you intend (a simple language) - perhaps it is more important to delineate your intentions first, and then attempt to validate whether Haskell or some other language fits your criteria as the best candidate in which to define your programming language.

While you are at it, you might want to checkout Dana Scott's Denotational Semantics and take a look at Lambda Calculus as a potential language in which to define your programming language (if you are up to the challenge). Even simple languages, in order to be useful, should be well-defined semantically.

Tom
  • 1
  • I basically read this as: "Beginner programmer, you need to learn maths then publish a paper before you can have a programming language, and don't do it in the language you're doing it in." – luqui Oct 27 '11 at 20:54
-3

Design And Implementations Of Languages Of

W.Pratt is good book to read , after that it is better to read aho compiler book.

But after all of this ; you need some algorithms for compilers and some principals that you should follow.

For example you should write a scanner , Which checks errors in variable names for exmaple.

For example a C++ scanner will find error in below code :

int 32xy=0;

Because the c++ variables cannot start with a digit.

So far a scanner has a symbol table that holds the errors . the scanner will send the symbol table to parser now.

enter image description here

Now we will write a parser .

notice that my answer is pervasive.

S.A.Parkhid
  • 2,772
  • 6
  • 28
  • 58
  • 1
    This seriously looks like a bunch of comments cutted-and-pasted from somewhere and doesn't even relate to Haskell at all... – alternative Oct 27 '11 at 16:46
  • 1
    "So far a scanner has a symbol table that holds the errors . the scanner will send the symbol table to parser now." Sounds like a comment from a tutorial/blog post showing how to implement a scanner. – alternative Oct 28 '11 at 16:06