{- ASTCG (Abstract Syntax Tree Code Generator). This is a small program that aims to use a very simple grammar to generate data structures (for AST obviously) in a variety of target languages. IMPORTANT: This is a pre-release version of the code, there is no parser yet. The AST must be built inside the haskell interpreter using the data types defined in this module. Copyright (C) 2012 Victor Cacciari Miraldo This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . -} module AST where {- A ASTField is something that contains data. It must have a name and a type. The type must be compilant in the target language. -} data ASTField = ASTField String String deriving Show {- Well, one node of the same type can have different (and disjoint) cases. For instance, one atom can be a variable or a number. In C, this will correspond to a union. A "kind" is called by it's name, and itself can be a composite field (struct) or a single value. -} data ASTKind = ASTKind String [ASTField] | ASTAtomKind ASTField -- Since ASTKind can assume different forms, we should provide some interface functions -- for making the implementation of the target translators easier. kindName :: ASTKind -> String kindName (ASTKind n _) = n kindName (ASTAtomKind (ASTField _ n)) = n kindFields :: ASTKind -> [ASTField] kindFields (ASTKind _ f) = f kindFields (ASTAtomKind f) = [f] {- A ASTNode will correspond to a struct/class in the target language, It must have a name, a list of fields and a list of kind-specific fields, which will correspond to a union (in C). -} data ASTNode = ASTNode String [ASTField] [ASTKind] {- Finally, a complete grammar needs different nodes, so one ASTProgram will be a list of nodes, a header and a footer. Both the header and the footer must be compilant code in the target language, they'll be added before and after the declaration of the AST created data types. TODO: Add the possibility to use options. -} data ASTProgram = ASTProgram String String [ASTNode] {- TODO: the parsing interface to generate the ASTProgram. -} {- Example program. Used for testing purposes only. -} expKinds = [ ASTKind "binop" [(ASTField "int" "op"), (ASTField "Exp*" "lh"), (ASTField "Exp*" "rh")], ASTAtomKind (ASTField "Symbol*" "builtin"), ASTKind "app" [(ASTField "Symbol*" "f"), (ASTField "Exp*" "arg")] ] expNode = ASTNode "Exp" [(ASTField "int" "line")] expKinds varNode = ASTNode "VarDecl" [(ASTField "int" "line"), (ASTField "Symbol*" "name")] [] myProg = ASTProgram "#ifndef EXP_TEST_H\n#define EXP_TEST_H\n\n#include \"test.h\"\n\n" "#endif\n\n\n/* I M P L E M E N T A T I O N */\n#include \"exp_test.h\"\n#define ALLOC(type) (type*)my_allocator(sizeof(type))\n\n" [expNode, varNode]