grammar fixes, grammar returns, fixes

This commit is contained in:
ProgramSnail 2025-06-14 16:53:36 +03:00
parent da785b2faf
commit 515207481f
4 changed files with 109 additions and 34 deletions

View file

@ -36,8 +36,9 @@ public class LamaLanguage extends TruffleLanguage<LamaContext> {
public static final String ID = "lama"; public static final String ID = "lama";
public static final String MIME_TYPE = "application/x-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 @Override
protected CallTarget parse(ParsingRequest request) throws Exception { protected CallTarget parse(ParsingRequest request) throws Exception {

View file

@ -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());
}
}

View file

@ -110,43 +110,44 @@ public static LamaExpressionNode parseLama(LamaLanguage language, Source source)
// parser // parser
lama : (import_expression)* scope_expression EOF; lama : /* (import_expression)* */ scope_expression EOF;
import_expression : 'import' UIDENT ';'; //import_expression : 'import' UIDENT ';';
scope_expression : scope_expression :
definition+ (expression)? definition+ (expression)?
| expression; | expression;
definition : definition returns [LamaExpressionNode result]:
variable_definition variable_definition
| function_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_sequence : variable_definition_item (',' variable_definition_item)* ';';
variable_definition_item : LIDENT ('=' basic_expression)?; 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_arguments : LIDENT (',' LIDENT)*;
function_body : '{' scope_expression '}'; function_body returns [LamaExpressionNode result]: '{' scope_expression '}';
// //
infix_definition : infix_head '(' function_arguments ')' function_body; //infix_definition : infix_head '(' function_arguments ')' function_body;
infix_head : ('public')? infixity INFIX level; //infix_head : ('public')? infixity INFIX level;
infixity : 'infix' | 'infixl' | 'infixr'; //infixity : 'infix' | 'infixl' | 'infixr';
level : ('at' | 'before' | 'after') INFIX; //level : ('at' | 'before' | 'after') any_infix;
// //
expression returns [LamaExpressionNode result]: basic_expression (';' expression)?; expression returns [LamaExpressionNode result]: basic_expression (';' expression)?;
basic_expression returns [LamaExpressionNode result]: binary_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 returns [LamaExpressionNode result]: ('-')? primary (postfix)*;
postfix : postfix :
'(' expression (',' expression)* ')' '(' expression (',' expression)* ')'
| '(' ')'
| '[' expression ']'; | '[' expression ']';
primary returns [LamaExpressionNode result]: primary returns [LamaExpressionNode result]:
@ -156,7 +157,7 @@ primary returns [LamaExpressionNode result]:
| LIDENT | LIDENT
| 'true' | 'true'
| 'false' | 'false'
| 'infix' INFIX | 'infix' any_infix
| 'fun' '(' function_arguments ')' function_body | 'fun' '(' function_arguments ')' function_body
| 'skip' | 'skip'
| '(' scope_expression ')' | '(' scope_expression ')'
@ -172,34 +173,34 @@ primary returns [LamaExpressionNode result]:
// //
array_expression : '[' (expression (',' expression)* )? ']'; array_expression returns [LamaExpressionNode result]: '[' (expression (',' expression)* )? ']';
list_expression : '{' (expression (',' expression)* )? '}'; list_expression returns [LamaExpressionNode result]: '{' (expression (',' expression)* )? '}';
s_expression : /*TODO */ UIDENT ('(' (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 : else_part :
'elif' expression 'then' scope_expression (else_part)? 'elif' expression 'then' scope_expression (else_part)?
| 'else' scope_expression; | 'else' scope_expression;
// //
while_do_expression : 'while' expression 'do' scope_expression 'od'; while_do_expression returns [LamaExpressionNode result]: 'while' expression 'do' scope_expression 'od';
do_while_expression : 'do' scope_expression 'while' expression 'od'; do_while_expression returns [LamaExpressionNode result]: 'do' scope_expression 'while' expression 'od';
for_expression : 'for' scope_expression ',' expression ',' expression 'do' scope_expression 'od'; for_expression returns [LamaExpressionNode result]: 'for' scope_expression ',' expression ',' expression 'do' scope_expression 'od';
// //
pattern: cons_pattern '|' simple_pattern; pattern returns [LamaPattern result]: cons_pattern | simple_pattern;
cons_pattern : simple_pattern ':' pattern; cons_pattern returns [LamaPattern result]: simple_pattern ':' pattern;
simple_pattern : simple_pattern returns [LamaPattern result]:
wildcard_pattern wildcard_pattern
| s_expr_pattern | s_expr_pattern
| array_pattern | array_pattern
| list_pattern | list_pattern
| LIDENT ('@' pattern)? | LIDENT ('@' pattern)?
| ('-')? DECIMAL_LITERAL | (MINUS)? DECIMAL_LITERAL
| STRING_LITERAL | STRING_LITERAL
| CHAR_LITERAL | CHAR_LITERAL
| 'true' | 'true'
@ -213,17 +214,21 @@ simple_pattern :
| '(' pattern ')' | '(' pattern ')'
; ;
wildcard_pattern : '_'; wildcard_pattern returns [LamaPattern result]: '_';
s_expr_pattern : UIDENT ('(' (pattern (',' pattern)*)? ')')?; s_expr_pattern returns [LamaPattern result]: UIDENT ('(' (pattern (',' pattern)*)? ')')?;
array_pattern : '[' (pattern (',' pattern)*)? ']'; array_pattern returns [LamaPattern result]: '[' (pattern (',' pattern)*)? ']';
list_pattern : '{' (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_branches : case_branch ('|' case_branch)*;
case_branch : pattern '->' scope_expression; case_branch : pattern '->' scope_expression;
//
any_infix : INFIX | MINUS;
// lexer // lexer
WS : [ \t\r\n\u000C]+ -> skip; WS : [ \t\r\n\u000C]+ -> skip;
@ -234,8 +239,7 @@ fragment NON_ZERO_DIGIT : [1-9];
fragment DIGIT : [0-9]; fragment DIGIT : [0-9];
fragment STRING_CHAR : ~('"' | '\r' | '\n'); fragment STRING_CHAR : ~('"' | '\r' | '\n');
WORD : [a-zA-Z_0-9]+; MINUS: '-';
INFIX : [+*/%$#@!|&^?<>.:=\-]+; INFIX : [+*/%$#@!|&^?<>.:=\-]+;
UIDENT : [A-Z][a-zA-Z_0-9]*; UIDENT : [A-Z][a-zA-Z_0-9]*;
LIDENT : [a-z][a-zA-Z_0-9]*; LIDENT : [a-z][a-zA-Z_0-9]*;
@ -243,3 +247,5 @@ LIDENT : [a-z][a-zA-Z_0-9]*;
CHAR_LITERAL : '\'' STRING_CHAR '\''; CHAR_LITERAL : '\'' STRING_CHAR '\'';
STRING_LITERAL : '"' STRING_CHAR* '"'; STRING_LITERAL : '"' STRING_CHAR* '"';
DECIMAL_LITERAL : '0' | ('-'?) NON_ZERO_DIGIT DIGIT*; DECIMAL_LITERAL : '0' | ('-'?) NON_ZERO_DIGIT DIGIT*;
WORD : [a-zA-Z_0-9]+;

View file

@ -1,12 +1,61 @@
package org.programsnail.truffle_lama.parser; 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.source.Source;
import com.oracle.truffle.api.strings.TruffleString;
import org.programsnail.truffle_lama.LamaLanguage; import org.programsnail.truffle_lama.LamaLanguage;
import org.programsnail.truffle_lama.LamaStrings;
import org.programsnail.truffle_lama.nodes.LamaExpressionNode; import org.programsnail.truffle_lama.nodes.LamaExpressionNode;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class LamaNodeFactory { public class LamaNodeFactory {
static class LexicalScope {
protected final LexicalScope outer;
protected final Map<TruffleString, Integer> 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<TruffleString, RootCallTarget> 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) { 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() { public LamaExpressionNode getRootExpr() {