--- In ocaml_beginners%40yahoogroups.com">ocaml_beginners
yahoogroups.com, Karl Zilles <zilles
...> wrote:
>
> mo.deeq wrote:
> > definitions are fairly simple have the form
> >
> > my_type my_var = my_value
> >
> > i.e.
> >
> > int a = 1 ;
> > char v = "v";
> > foo bar = foobar
> >
> > where the only 1 constraint that object on the left and right hand
> > side of the assignment *must* be of the same type and as such the type
> > of a variable must be know before it can be used in an assignment, so
> > that a user is able to write code such as
> >
> > foo foobar = ..;
> >
> > foo bar = foobar;
> >
> >
> > the types and assignments are defined by the user of the language as
> > and when required in their program, i don't enforce any specific
> > constraints.
>
> It looks like you're writing an interpreter for a language. Is this a
> well know language, or one you're creating?
>
> If it's one you're creating, what is the syntax for defining a type?
>
> Here's what I'm getting at... Let's say that your variable storage type
> (in ocaml) is:
>
> type variable = String of string | Int of int | Block of variable
array;;
>
> Then if your user defined a "person" record type in your language with
> two fields, say an string called "name" and a integer called "age", you
> could use the "variable" type to store the person like so:
>
> Block [| String "Hello"; Int 47 |];;
>
> (Your interpreter would remember that "name" is always the first index
> into a "person" and age always the second.)
>
Hi Karl, yes its an interpreter for my own language. I havent defined
any thing as complex as record, though i would like to, the parser
gives the following;
declaration_list
: declaration{[$1]}
| declaration_list declaration{$1
[$2]}
;
declarator_list
: declarator {[$1]}
| declarator_list COMMA declarator{$1
[$3]}
;
declaration
: type_specifier SEMICOLON
{Declaration($1, None, !Lexer.line_counter)}
| type_specifier declarator_list SEMICOLON
{Declaration($1, Some(DeclaratorList($2)), !Lexer.line_counter)}
;
declarator
: identifier
{Declarator($1)}
| PARENTHESIS_OPEN declarator PARENTHESIS_CLOSE
{Declarator($2)}
| declarator BRACKET_OPEN constant_expression BRACKET_CLOSE
{DeclaratorArray($1, $3)}
;
type_specifier
: IDENT {Type(TypeSingle ($1))}
;
This is used to build the AST. where in the AST, a type is very dump
and defined as:
type basic_type =
TypeSingle of string
| TypeComposite of string * string
| None
and the declarations and declarators are:
type ast =
...
| DeclarationList of ast list
| Declaration of ast * ast option * int
| Declarator of ast
| DeclaratorList of ast list
| DeclaratorArray of ast * ast
so for example, given
int a, b;
foo bar;
foo foobar ;
bar = foobar;
we produce the following AST
DeclarationList(
Declaration(Type(TypeInt),
DeclaratorList(
Declarator(Identifier(a)),
Declarator(Identifier(b))
)
),
Declaration(Type(foo),
DeclaratorList(
Declarator(Identifier(bar))
)
),
Declaration(Type(foo),
DeclaratorList(
Declarator(Identifier(foobar))
)
)
),
and the assignment ends up being represented as:
ExpressionStatement(Expression(
AssignmentExpression(
Identifier(bar),
Assignment,
Identifier(foobar)
))),
thanks
-- deeq
.