ast.go 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  1. package ast
  2. import (
  3. "bytes"
  4. "code.osinet.fr/fgm/waiig15/token"
  5. )
  6. // The base Node interface
  7. // Node is the interface implemented by every node in the AST. It extends the
  8. // fmt.Stringer interface, allowing simple printing of nodes.
  9. type Node interface {
  10. // TokenLiteral returns the literal value of the token it's associated to.
  11. TokenLiteral() string
  12. String() string
  13. }
  14. // All statement nodes implement this
  15. // Statement extends Node and is only a way to differentiate between expressions
  16. // and statements.
  17. type Statement interface {
  18. Node
  19. statementNode()
  20. }
  21. // All expression nodes implement this
  22. // Expression extends Node and is only a way to differentiate between
  23. // expressions and statements.
  24. type Expression interface {
  25. // Expression extends Node.
  26. Node
  27. expressionNode()
  28. }
  29. // Program represents the outer structure of the parser program.
  30. type Program struct {
  31. Statements []Statement
  32. }
  33. // TokenLiteral returns the string contents of the first statement token, which
  34. // can be an empty string if the program is empty.
  35. func (p *Program) TokenLiteral() string {
  36. if len(p.Statements) > 0 {
  37. return p.Statements[0].TokenLiteral()
  38. }
  39. return ""
  40. }
  41. // String satisfies the Node and fmt.Stringer interfaces.
  42. func (p *Program) String() string {
  43. var out bytes.Buffer
  44. for _, s := range p.Statements {
  45. out.WriteString(s.String())
  46. }
  47. return out.String()
  48. }
  49. // LetStatement is the Node type for Let statements.
  50. type LetStatement struct {
  51. Token token.Token // the token.LET token. Why do we need it ?
  52. Name *Identifier
  53. Value Expression
  54. }
  55. func (ls *LetStatement) statementNode() {}
  56. // TokenLiteral satisfies the Node interface.
  57. func (ls *LetStatement) TokenLiteral() string {
  58. return ls.Token.Literal
  59. }
  60. // String implements Node and fmt.Stringer.
  61. func (ls *LetStatement) String() string {
  62. var out bytes.Buffer
  63. out.WriteString(ls.TokenLiteral() + " ")
  64. out.WriteString(ls.Name.String())
  65. out.WriteString(" = ")
  66. if ls.Value != nil {
  67. out.WriteString(ls.Value.String())
  68. }
  69. out.WriteString(";")
  70. return out.String()
  71. }
  72. // ReturnStatement fulfills the Node and Statement interfaces.
  73. type ReturnStatement struct {
  74. Token token.Token // the token.RETURN token. Why do we need it ?
  75. Name *Identifier
  76. ReturnValue Expression
  77. }
  78. func (rs *ReturnStatement) statementNode() {}
  79. // TokenLiteral satisfies the Node interface.
  80. func (rs *ReturnStatement) TokenLiteral() string {
  81. return rs.Token.Literal
  82. }
  83. // String satisfies the Node and fmt.Stringer interfaces.
  84. func (rs *ReturnStatement) String() string {
  85. var out bytes.Buffer
  86. out.WriteString(rs.TokenLiteral() + " ")
  87. if rs.ReturnValue != nil {
  88. out.WriteString(rs.ReturnValue.String())
  89. }
  90. out.WriteString(";")
  91. return out.String()
  92. }
  93. // ExpressionStatement fulfills the Node and Statement interfaces.
  94. // It represents a statement made of a bare expression like:
  95. // x + 10;
  96. type ExpressionStatement struct {
  97. Token token.Token // the first token of the expression
  98. Expression Expression
  99. }
  100. func (es *ExpressionStatement) statementNode() {}
  101. // TokenLiteral satisfies the Node interface.
  102. func (es *ExpressionStatement) TokenLiteral() string {
  103. return es.Token.Literal
  104. }
  105. // String satisfies the Node and fmt.Stringer interfaces.
  106. func (es *ExpressionStatement) String() string {
  107. if es.Expression != nil {
  108. return es.Expression.String()
  109. }
  110. return ""
  111. }
  112. // BlockStatement fulfills the Node and Statement interfaces.
  113. // It represents a suite of statements.
  114. type BlockStatement struct {
  115. Token token.Token // the { token
  116. Statements []Statement
  117. }
  118. func (bs *BlockStatement) statementNode() {}
  119. // TokenLiteral satisfies the Node interface.
  120. func (bs *BlockStatement) TokenLiteral() string {
  121. return bs.Token.Literal
  122. }
  123. // String satisfies the Node and fmt.Stringer interfaces.
  124. func (bs *BlockStatement) String() string {
  125. var out bytes.Buffer
  126. for _, s := range bs.Statements {
  127. out.WriteString(s.String())
  128. }
  129. return out.String()
  130. }
  131. // Identifier is the Node type for identifiers.
  132. type Identifier struct {
  133. Token token.Token // the token.IDENT token. Why do we need it ?
  134. Value string // The identifier string.
  135. }
  136. func (i *Identifier) expressionNode() {}
  137. // TokenLiteral satisfies the Node interface.
  138. func (i *Identifier) TokenLiteral() string {
  139. return i.Token.Literal
  140. }
  141. func (i *Identifier) String() string {
  142. return i.Value
  143. }
  144. // Boolean is the Node type for booleans.
  145. type Boolean struct {
  146. Token token.Token
  147. Value bool // true or false, for the equivalent Monkey tokens.
  148. }
  149. func (b *Boolean) expressionNode() {}
  150. func (b *Boolean) TokenLiteral() string {
  151. return b.Token.Literal
  152. }
  153. func (b *Boolean) String() string {
  154. return b.Token.Literal
  155. }
  156. // IntegerLiteral fulfills ast.Expression.
  157. type IntegerLiteral struct {
  158. Token token.Token
  159. Value int64
  160. }
  161. func (il *IntegerLiteral) expressionNode() {}
  162. // TokenLiteral satisfies the Node interface.
  163. func (il *IntegerLiteral) TokenLiteral() string {
  164. return il.Token.Literal
  165. }
  166. func (il *IntegerLiteral) String() string {
  167. return il.Token.Literal
  168. }
  169. // PrefixExpression fulfills the Node and Expression interfaces.
  170. // It represents a prefixed expression like:
  171. // "-5;"
  172. type PrefixExpression struct {
  173. Token token.Token // The prefix token, e.g. !
  174. Operator string
  175. Right Expression
  176. }
  177. func (pe *PrefixExpression) expressionNode() {}
  178. // TokenLiteral satisfies the Node interface.
  179. func (pe *PrefixExpression) TokenLiteral() string {
  180. return pe.Token.Literal
  181. }
  182. // String satisfies the Node and fmt.Stringer interfaces.
  183. func (pe *PrefixExpression) String() string {
  184. var out bytes.Buffer
  185. out.WriteString("(")
  186. out.WriteString(pe.Operator)
  187. out.WriteString(pe.Right.String())
  188. out.WriteString(")")
  189. return out.String()
  190. }
  191. // InfixExpression fulfills the Node and Expression interfaces.
  192. // It represents an infix expression like:
  193. // "5 + 6;"
  194. type InfixExpression struct {
  195. Token token.Token // The operator token, e.g. +
  196. Left Expression
  197. Operator string
  198. Right Expression
  199. }
  200. func (ie *InfixExpression) expressionNode() {}
  201. // TokenLiteral satisfies the Node interface.
  202. func (ie *InfixExpression) TokenLiteral() string {
  203. return ie.Token.Literal
  204. }
  205. // String satisfies the Node and fmt.Stringer interfaces.
  206. func (ie *InfixExpression) String() string {
  207. var out bytes.Buffer
  208. out.WriteString("(")
  209. out.WriteString(ie.Left.String())
  210. out.WriteString(" " + ie.Operator + " ")
  211. out.WriteString(ie.Right.String())
  212. out.WriteString(")")
  213. return out.String()
  214. }
  215. // IfExpression fulfills the Node and Expression interfaces.
  216. // It represents a condition expression like:
  217. // "if true 5 else 6;"
  218. // Note that if/else are expressions, not just statements.
  219. type IfExpression struct {
  220. Token token.Token // The "if" token
  221. Condition Expression
  222. Consequence *BlockStatement
  223. Alternative *BlockStatement
  224. }
  225. func (ie *IfExpression) expressionNode() {}
  226. // TokenLiteral satisfies the Node interface.
  227. func (ie *IfExpression) TokenLiteral() string {
  228. return ie.Token.Literal
  229. }
  230. // String satisfies the Node and fmt.Stringer interfaces.
  231. func (ie *IfExpression) String() string {
  232. var out bytes.Buffer
  233. out.WriteString("if")
  234. out.WriteString(ie.Condition.String())
  235. out.WriteString(" ")
  236. out.WriteString(ie.Consequence.String())
  237. if ie.Alternative != nil {
  238. out.WriteString("else ")
  239. out.WriteString(ie.Alternative.String())
  240. }
  241. return out.String()
  242. }