Skip to content

Instantly share code, notes, and snippets.

@ProjectMoon
Created May 4, 2011 16:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ProjectMoon/955488 to your computer and use it in GitHub Desktop.
Save ProjectMoon/955488 to your computer and use it in GitHub Desktop.
Function Expressions: first file is the grammar I want to use, demonstrating the problem. The second (example.eve) demonstrates what must be done currently in the language vs what I would like to achieve.
lib/
*.java
*.tokens
<project xmlns:ivy="antlib:org.apache.ivy.ant" name="eve-interpreter" default="antlr" basedir=".">
<!-- Build macro for antlr code generation -->
<macrodef name="antlr3">
<attribute name="grammar"/>
<attribute name="output" default="."/>
<attribute name="lib" default="."/>
<sequential>
<java classname="org.antlr.Tool" fork="true" failonerror="true">
<classpath>
<fileset dir="lib/" includes="*.jar" />
</classpath>
<arg value="-o"/>
<arg path="@{output}"/>
<arg value="-verbose"/>
<arg value="-make"/>
<arg path="@{grammar}"/>
</java>
</sequential>
</macrodef>
<!-- resolve all dependencies via Ivy -->
<target name="dependencies" description="--> retrieve dependencies with ivy">
<ivy:retrieve />
</target>
<target name="antlr" depends="dependencies" description="--> antlr code generation">
<antlr3 grammar="func.g" output="." />
</target>
</project>
//This is what must be done now, since functions can only be referenced by identifier.
var x = createFunction();
x();
//This is what I want to be able to do, among other things.
createFunction()();
grammar func;
options {
language = Java;
output = AST;
ASTLabelType = CommonTree;
}
tokens {
INVOKE_FUNCTION_STMT;
INVOKE_FUNCTION_EXPR;
NEGATION;
}
@header {
package eve.core;
}
@lexer::header {
package eve.core;
import java.util.List;
import java.util.ArrayList;
}
@lexer::members {
public void displayRecognitionError(String[] tokenNames, RecognitionException e) {
String hdr = getErrorHeader(e);
String msg = getErrorMessage(e, tokenNames);
throw new EveError(hdr + " " + msg);
}
public void recover(RecognitionException e) {
String hdr = getErrorHeader(e);
throw new EveError(hdr + " " + e.getMessage());
}
}
@parser::members {
private List<String> errors = new ArrayList<String>();
public void displayRecognitionError(String[] tokenNames, RecognitionException e) {
String hdr = getErrorHeader(e);
String msg = getErrorMessage(e, tokenNames);
errors.add(hdr + " " + msg);
}
public void recover(RecognitionException e) {
errors.add(e.getMessage());
}
public List<String> getErrors() {
return errors;
}
public boolean hasErrors() {
return errors.size() > 0;
}
}
//The original function invocation rules for expressions.
//Only identifies via identifier.
functionInvocationParameters
: expression (',' expression)* -> (expression)* //apparently this somehow rewrites the entire thing to "p1 p2 p3 ..."
;
functionInvocationExpression
: IDENT '(' functionInvocationParameters ')' -> ^(INVOKE_FUNCTION_EXPR IDENT functionInvocationParameters)
| IDENT '(' ')' -> ^(INVOKE_FUNCTION_EXPR IDENT)
;
//Expressions
term
: IDENT
| '('! expression ')'!
| INTEGER
| DOUBLE
| BOOLEAN
//have this one commented out, because it's the old way.
//| functionInvocationExpression
| expression '(' ')' -> ^(INVOKE_FUNCTION_EXPR IDENT)
| expression '(' functionInvocationParameters ')' -> ^(INVOKE_FUNCTION_EXPR IDENT functionInvocationParameters)
;
boolNegation
: '!'* term
;
unary
: ('+'! | negation^)* boolNegation
;
negation
: '-' -> NEGATION
;
mult
: unary (('*'^ | '/'^ | '%'^) unary)*
;
add
: mult (('+'^ | '-'^ | '~'^) mult)*
;
relation
: add (('=='^ | '!='^ | '<'^ | '<='^ | '>='^ | '>'^) add)*
;
expression
: relation (('&&'^ | '||'^) relation)*
;
// Tokens
fragment LETTER : ('a'..'z' | 'A'..'Z') ;
fragment DIGIT : '0'..'9';
INTEGER : DIGIT+ ;
DOUBLE : DIGIT+ '.' DIGIT+ ;
BOOLEAN : 'true' | 'false' ;
IDENT : LETTER (LETTER | DIGIT)*;
WS : (' ' | '\t' | '\n' | '\r' | '\f')+ {$channel = HIDDEN;};
<ivy-module version="2.0">
<info organisation="thermetics.eve" module="eve-interpreter" />
<dependencies>
<dependency org="org.antlr" name="antlr" rev="3.3" />
</dependencies>
</ivy-module>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment