View Javadoc

1   ////////////////////////////////////////////////////////////////////////////////
2   // MillScript: an Open Spice interpreter and batch website creation tool
3   // Copyright (C) 2001-2004 Open World Ltd
4   // Copyright (C) 2004-2005 Kevin Rogers
5   //
6   // This file is part of MillScript.
7   //
8   // MillScript is free software; you can redistribute it and/or modify it under
9   // the terms of the GNU General Public License as published by the Free
10  // Software Foundation; either version 2 of the License, or (at your option)
11  // any later version.
12  //
13  // MillScript is distributed in the hope that it will be useful, but WITHOUT
14  // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15  // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
16  // more details.
17  //
18  // You should have received a copy of the GNU General Public License along with
19  // MillScript; if not, write to the Free Software Foundation, Inc., 59 Temple
20  // Place, Suite 330, Boston, MA  02111-1307  USA
21  ////////////////////////////////////////////////////////////////////////////////
22  package org.millscript.millscript.syntax;
23  
24  import org.millscript.millscript.alert.Alerts;
25  import org.millscript.millscript.expr.Expr;
26  
27  /**
28   * This class implements <code>define</code> syntax. This is used to define
29   * functions, memos and classes. This syntax defines a variable and binds it to
30   * the specified expression, e.g. a function object is bound to a variable with
31   * the same name as the function.
32   *
33   * @see org.millscript.millscript.expr.LambdaExpr
34   * @see org.millscript.millscript.expr.MemoExpr
35   * @see org.millscript.millscript.expr.SpiceClassExpr
36   * @see org.millscript.millscript.expr.VarExpr
37   */
38  public final class DefineSyntax extends PrefixSyntax {
39  
40      /**
41       * Function syntax parser for use within a define statement. This is
42       * required as within a define statement, a function definition ends with
43       * "enddefine" rather than "endfunction".
44       */
45      private final FunctionSyntax func = new FunctionSyntax( "enddefine" );
46  
47      /**
48       * Init procedure syntax parser for use within a define statement. This is
49       * required as within a define statement, an init procedure definition ends
50       * with "enddefine".
51       */
52      private final SpiceClassInitSyntax init = new SpiceClassInitSyntax( "enddefine" );
53  
54      /**
55       * Memo function syntax parser for use within a define statement. This is
56       * required as within a define statement, a memo function definition ends
57       * with "enddefine".
58       */
59      private final MemoSyntax memo = new MemoSyntax( "enddefine" );
60  
61      /**
62       * Method syntax parser for use within a define statement.
63       */
64      private final MethodSyntax method = new MethodSyntax( "enddefine" );
65  
66      /**
67       * Method override syntax parser for use within a define statement.
68       */
69      private final MethodOverrideSyntax methodOverride = new MethodOverrideSyntax( "enddefine" );
70  
71      /**
72       * Class syntax parser for use within a define statement. This is required
73       * as within a define statement, a class definition ends with "enddefine".
74       */
75      private final SpiceClassSyntax spiceClass = new SpiceClassSyntax( "enddefine" );
76  
77      /**
78       * @see org.millscript.millscript.syntax.PrefixSyntaxInterface#prefix(java.lang.String, org.millscript.millscript.syntax.Parser)
79       */
80      @Override
81      public Expr prefix( final String sym, final Parser parser ) {
82          // Now, what kind of thing are we trying to define
83          if ( parser.tryRead( "override" ) || parser.tryRead( "method" ) ) {
84              if ( parser.peekRead( "^" ) ) {
85                  // we're defining a method override
86                  return methodOverride.prefix( sym, parser );
87              } else {
88                  // We can only define an override for a method.
89                  throw(
90                      Alerts.parse(
91                          "Unexpected token after 'override'",
92                          "Only methods can be overridden"
93                      ).culprit( "token", parser.getErrorString() ).mishap()
94                  );
95              }
96          } else if ( parser.tryRead( "function" ) ) {
97              // we're defining a function
98              // call the function syntax parser and return a function expression
99              return func.prefix( sym, parser );
100         } else if ( parser.tryRead( "memo" ) ) {
101             // we're defining a memo
102             // call the memo syntax parser and return a memo expression
103             return memo.prefix( sym, parser );
104         } else if ( parser.tryRead( "class" ) ) {
105             // we're defining a class
106             // call the class syntax parser and return a class expression
107             return spiceClass.prefix( sym, parser );
108         } else if ( parser.peekRead( "^" ) ) {
109             // we're defining a method
110             return method.prefix( sym, parser );
111         } else if ( parser.tryRead( "init" ) ) {
112             // we're defining an initialiser
113             return init.prefix( sym, parser );
114         } else {
115             // we can only define classes, functions and memos at the moment
116             throw(
117                 Alerts.parse(
118                     "Unexpected token after 'define'",
119                     "Requires 'class', 'function', 'memo', '^', 'init' or 'override'"
120                 ).culprit( "token", parser.getErrorString() ).mishap()
121             );
122         }
123     }
124 
125 }