diff --git a/src/main/java/org/programsnail/truffle_lama/LamaLanguage.java b/src/main/java/org/programsnail/truffle_lama/LamaLanguage.java index 288e4a2..d4a6caa 100644 --- a/src/main/java/org/programsnail/truffle_lama/LamaLanguage.java +++ b/src/main/java/org/programsnail/truffle_lama/LamaLanguage.java @@ -36,8 +36,9 @@ public class LamaLanguage extends TruffleLanguage { public static final String ID = "lama"; public static final String MIME_TYPE = "application/x-lama"; - private final Assumption singleContext = Truffle.getRuntime().createAssumption("Single Lama context."); + public static final TruffleString.Encoding STRING_ENCODING = TruffleString.Encoding.UTF_16; + private final Assumption singleContext = Truffle.getRuntime().createAssumption("Single Lama context."); @Override protected CallTarget parse(ParsingRequest request) throws Exception { diff --git a/src/main/java/org/programsnail/truffle_lama/LamaStrings.java b/src/main/java/org/programsnail/truffle_lama/LamaStrings.java new file mode 100644 index 0000000..89076fa --- /dev/null +++ b/src/main/java/org/programsnail/truffle_lama/LamaStrings.java @@ -0,0 +1,19 @@ +package org.programsnail.truffle_lama; + +import com.oracle.truffle.api.strings.TruffleString; + +public final class LamaStrings { + public static TruffleString fromJavaString(String s) { + return TruffleString.fromJavaStringUncached(s, LamaLanguage.STRING_ENCODING); + } + + public static TruffleString fromObject(Object o) { + if (o == null) { + return fromJavaString("null"); + } + if (o instanceof TruffleString) { + return (TruffleString) o; + } + return fromJavaString(o.toString()); + } +} diff --git a/src/main/java/org/programsnail/truffle_lama/parser/Lama.g4 b/src/main/java/org/programsnail/truffle_lama/parser/Lama.g4 index 15fcdd8..2eb1d1b 100644 --- a/src/main/java/org/programsnail/truffle_lama/parser/Lama.g4 +++ b/src/main/java/org/programsnail/truffle_lama/parser/Lama.g4 @@ -110,43 +110,44 @@ public static LamaExpressionNode parseLama(LamaLanguage language, Source source) // parser -lama : (import_expression)* scope_expression EOF; +lama : /* (import_expression)* */ scope_expression EOF; -import_expression : 'import' UIDENT ';'; +//import_expression : 'import' UIDENT ';'; scope_expression : definition+ (expression)? | expression; -definition : +definition returns [LamaExpressionNode result]: variable_definition | function_definition - | infix_definition; +// | infix_definition; // -variable_definition : ('var' | 'public') variable_definition_sequence; +variable_definition: ('var' | 'public') variable_definition_sequence; variable_definition_sequence : variable_definition_item (',' variable_definition_item)* ';'; variable_definition_item : LIDENT ('=' basic_expression)?; -function_definition : ('public')? 'fun' LIDENT '(' (function_arguments)? ')' function_body; +function_definition returns [LamaExpressionNode result]: ('public')? 'fun' LIDENT '(' (function_arguments)? ')' function_body; function_arguments : LIDENT (',' LIDENT)*; -function_body : '{' scope_expression '}'; +function_body returns [LamaExpressionNode result]: '{' scope_expression '}'; // -infix_definition : infix_head '(' function_arguments ')' function_body; -infix_head : ('public')? infixity INFIX level; -infixity : 'infix' | 'infixl' | 'infixr'; -level : ('at' | 'before' | 'after') INFIX; +//infix_definition : infix_head '(' function_arguments ')' function_body; +//infix_head : ('public')? infixity INFIX level; +//infixity : 'infix' | 'infixl' | 'infixr'; +//level : ('at' | 'before' | 'after') any_infix; // expression returns [LamaExpressionNode result]: basic_expression (';' expression)?; basic_expression returns [LamaExpressionNode result]: binary_expression; -binary_expression returns [LamaExpressionNode result]: postfix_expression (INFIX postfix_expression)*; +binary_expression returns [LamaExpressionNode result]: postfix_expression (any_infix postfix_expression)*; postfix_expression returns [LamaExpressionNode result]: ('-')? primary (postfix)*; postfix : '(' expression (',' expression)* ')' + | '(' ')' | '[' expression ']'; primary returns [LamaExpressionNode result]: @@ -156,7 +157,7 @@ primary returns [LamaExpressionNode result]: | LIDENT | 'true' | 'false' - | 'infix' INFIX + | 'infix' any_infix | 'fun' '(' function_arguments ')' function_body | 'skip' | '(' scope_expression ')' @@ -172,34 +173,34 @@ primary returns [LamaExpressionNode result]: // -array_expression : '[' (expression (',' expression)* )? ']'; -list_expression : '{' (expression (',' expression)* )? '}'; -s_expression : /*TODO */ UIDENT ('(' (expression (',' expression)* )? ')')?; +array_expression returns [LamaExpressionNode result]: '[' (expression (',' expression)* )? ']'; +list_expression returns [LamaExpressionNode result]: '{' (expression (',' expression)* )? '}'; +s_expression returns [LamaExpressionNode result]: /*TODO */ UIDENT ('(' (expression (',' expression)* )? ')')?; // -if_expression : 'if' expression 'then' scope_expression (else_part)? 'fi'; +if_expression returns [LamaExpressionNode result]: 'if' expression 'then' scope_expression (else_part)? 'fi'; else_part : 'elif' expression 'then' scope_expression (else_part)? | 'else' scope_expression; // -while_do_expression : 'while' expression 'do' scope_expression 'od'; -do_while_expression : 'do' scope_expression 'while' expression 'od'; -for_expression : 'for' scope_expression ',' expression ',' expression 'do' scope_expression 'od'; +while_do_expression returns [LamaExpressionNode result]: 'while' expression 'do' scope_expression 'od'; +do_while_expression returns [LamaExpressionNode result]: 'do' scope_expression 'while' expression 'od'; +for_expression returns [LamaExpressionNode result]: 'for' scope_expression ',' expression ',' expression 'do' scope_expression 'od'; // -pattern: cons_pattern '|' simple_pattern; -cons_pattern : simple_pattern ':' pattern; -simple_pattern : +pattern returns [LamaPattern result]: cons_pattern | simple_pattern; +cons_pattern returns [LamaPattern result]: simple_pattern ':' pattern; +simple_pattern returns [LamaPattern result]: wildcard_pattern | s_expr_pattern | array_pattern | list_pattern | LIDENT ('@' pattern)? - | ('-')? DECIMAL_LITERAL + | (MINUS)? DECIMAL_LITERAL | STRING_LITERAL | CHAR_LITERAL | 'true' @@ -213,17 +214,21 @@ simple_pattern : | '(' pattern ')' ; -wildcard_pattern : '_'; -s_expr_pattern : UIDENT ('(' (pattern (',' pattern)*)? ')')?; -array_pattern : '[' (pattern (',' pattern)*)? ']'; -list_pattern : '{' (pattern (',' pattern)*)? '}'; +wildcard_pattern returns [LamaPattern result]: '_'; +s_expr_pattern returns [LamaPattern result]: UIDENT ('(' (pattern (',' pattern)*)? ')')?; +array_pattern returns [LamaPattern result]: '[' (pattern (',' pattern)*)? ']'; +list_pattern returns [LamaPattern result]: '{' (pattern (',' pattern)*)? '}'; // -case_expression : 'case' expression 'of' case_branches 'esac'; +case_expression returns [LamaExpressionNode result]: 'case' expression 'of' case_branches 'esac'; case_branches : case_branch ('|' case_branch)*; case_branch : pattern '->' scope_expression; +// + +any_infix : INFIX | MINUS; + // lexer WS : [ \t\r\n\u000C]+ -> skip; @@ -234,12 +239,13 @@ fragment NON_ZERO_DIGIT : [1-9]; fragment DIGIT : [0-9]; fragment STRING_CHAR : ~('"' | '\r' | '\n'); -WORD : [a-zA-Z_0-9]+; - +MINUS: '-'; INFIX : [+*/%$#@!|&^?<>.:=\-]+; UIDENT : [A-Z][a-zA-Z_0-9]*; LIDENT : [a-z][a-zA-Z_0-9]*; CHAR_LITERAL : '\'' STRING_CHAR '\''; STRING_LITERAL : '"' STRING_CHAR* '"'; -DECIMAL_LITERAL : '0' | ('-'?) NON_ZERO_DIGIT DIGIT*; \ No newline at end of file +DECIMAL_LITERAL : '0' | ('-'?) NON_ZERO_DIGIT DIGIT*; + +WORD : [a-zA-Z_0-9]+; \ No newline at end of file diff --git a/src/main/java/org/programsnail/truffle_lama/parser/LamaNodeFactory.java b/src/main/java/org/programsnail/truffle_lama/parser/LamaNodeFactory.java index 44b43ec..8a834a9 100644 --- a/src/main/java/org/programsnail/truffle_lama/parser/LamaNodeFactory.java +++ b/src/main/java/org/programsnail/truffle_lama/parser/LamaNodeFactory.java @@ -1,12 +1,61 @@ package org.programsnail.truffle_lama.parser; +import com.oracle.truffle.api.RootCallTarget; +import com.oracle.truffle.api.frame.FrameDescriptor; import com.oracle.truffle.api.source.Source; +import com.oracle.truffle.api.strings.TruffleString; import org.programsnail.truffle_lama.LamaLanguage; +import org.programsnail.truffle_lama.LamaStrings; import org.programsnail.truffle_lama.nodes.LamaExpressionNode; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + public class LamaNodeFactory { + static class LexicalScope { + protected final LexicalScope outer; + protected final Map locals; + + LexicalScope(LexicalScope outer) { + this.outer = outer; + this.locals = new HashMap<>(); + } + + public Integer find(TruffleString name) { + Integer result = locals.get(name); + if (result != null) { + return result; + } else if (outer != null) { + return outer.find(name); + } else { + return null; + } + } + } + + /* State while parsing a source unit. */ + private final Source source; + private final TruffleString sourceString; +// private final Map allFunctions; // defined in scope + + /* State while parsing a function. */ + private int functionStartPos; + private TruffleString functionName; + private int functionBodyStartPos; // includes parameter list + private int argumentsCount; + private FrameDescriptor.Builder frameDescriptorBuilder; + private LamaExpressionNode functionBody; + + /* State while parsing an expr. */ + private LexicalScope lexicalScope; + private final LamaLanguage language; + public LamaNodeFactory(LamaLanguage language, Source source) { - // TODO + this.language = language; + this.source = source; + this.sourceString = LamaStrings.fromJavaString(source.getCharacters().toString()); +// this.allFunctions = new HashMap<>(); } public LamaExpressionNode getRootExpr() {