ast.go 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  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. // Identifier is the Node type for identifiers.
  113. type Identifier struct {
  114. Token token.Token // the token.IDENT token. Why do we need it ?
  115. Value string // The identifier string.
  116. }
  117. func (i *Identifier) expressionNode() {}
  118. // TokenLiteral satisfies the Node interface.
  119. func (i *Identifier) TokenLiteral() string {
  120. return i.Token.Literal
  121. }
  122. func (i *Identifier) String() string {
  123. return i.Value
  124. }
  125. // Boolean is the Node type for booleans.
  126. type Boolean struct {
  127. Token token.Token
  128. Value bool // true or false, for the equivalent Monkey tokens.
  129. }
  130. func (b *Boolean) expressionNode() {}
  131. func (b *Boolean) TokenLiteral() string {
  132. return b.Token.Literal
  133. }
  134. func (b *Boolean) String() string {
  135. return b.Token.Literal
  136. }
  137. // IntegerLiteral fulfills ast.Expression.
  138. type IntegerLiteral struct {
  139. Token token.Token
  140. Value int64
  141. }
  142. func (il *IntegerLiteral) expressionNode() {}
  143. // TokenLiteral satisfies the Node interface.
  144. func (il *IntegerLiteral) TokenLiteral() string {
  145. return il.Token.Literal
  146. }
  147. func (il *IntegerLiteral) String() string {
  148. return il.Token.Literal
  149. }
  150. // PrefixExpression fulfills the Node and Statement interfaces.
  151. // It represents a prefixed expression like:
  152. // "-5;"
  153. type PrefixExpression struct {
  154. Token token.Token // The prefix token, e.g. !
  155. Operator string
  156. Right Expression
  157. }
  158. func (pe *PrefixExpression) expressionNode() {}
  159. // TokenLiteral satisfies the Node interface.
  160. func (pe *PrefixExpression) TokenLiteral() string {
  161. return pe.Token.Literal
  162. }
  163. // String satisfies the Node and fmt.Stringer interfaces.
  164. func (pe *PrefixExpression) String() string {
  165. var out bytes.Buffer
  166. out.WriteString("(")
  167. out.WriteString(pe.Operator)
  168. out.WriteString(pe.Right.String())
  169. out.WriteString(")")
  170. return out.String()
  171. }
  172. // InfixExpression fulfills the Node and Statement interfaces.
  173. // It represents a prefixed expression like:
  174. // "-5;"
  175. type InfixExpression struct {
  176. Token token.Token // The operator token, e.g. +
  177. Left Expression
  178. Operator string
  179. Right Expression
  180. }
  181. func (ie *InfixExpression) expressionNode() {}
  182. // TokenLiteral satisfies the Node interface.
  183. func (ie *InfixExpression) TokenLiteral() string {
  184. return ie.Token.Literal
  185. }
  186. // String satisfies the Node and fmt.Stringer interfaces.
  187. func (ie *InfixExpression) String() string {
  188. var out bytes.Buffer
  189. out.WriteString("(")
  190. out.WriteString(ie.Left.String())
  191. out.WriteString(" " + ie.Operator + " ")
  192. out.WriteString(ie.Right.String())
  193. out.WriteString(")")
  194. return out.String()
  195. }