use of dyvilx.tools.compiler.ast.expression.LambdaExpr in project Dyvil by Dyvil.
the class LambdaType method wrapLambda.
public LambdaExpr wrapLambda(IValue value) {
IType returnType = value.getType();
final LambdaExpr lambdaExpr = new LambdaExpr(value.getPosition(), null, 0);
lambdaExpr.setImplicitParameters(true);
lambdaExpr.setMethod(this.getFunctionalMethod());
lambdaExpr.setValue(value);
lambdaExpr.inferReturnType(this, returnType);
return lambdaExpr;
}
use of dyvilx.tools.compiler.ast.expression.LambdaExpr in project Dyvil by Dyvil.
the class ICall method toLambda.
default IValue toLambda(MarkerList markers, IContext context, int wildcards) {
SourcePosition position = this.getPosition();
final IParameter[] parameters = new IParameter[wildcards];
for (int i = 0; i < wildcards; i++) {
parameters[i] = new CodeParameter(null, position, Name.fromRaw("wildcard$" + i), Types.UNKNOWN, new AttributeList());
}
int parIndex = 0;
final IValue receiver = this.getReceiver();
if (receiver != null && receiver.isPartialWildcard()) {
this.setReceiver(receiver.withLambdaParameter(parameters[parIndex++]));
}
final ArgumentList arguments = this.getArguments();
for (int i = 0, size = arguments.size(); i < size; i++) {
final IValue argument = arguments.get(i, null);
if (argument.isPartialWildcard()) {
arguments.set(i, null, argument.withLambdaParameter(parameters[parIndex++]));
}
}
final LambdaExpr lambdaExpr = new LambdaExpr(position, parameters, wildcards);
lambdaExpr.setImplicitParameters(true);
lambdaExpr.setValue(this);
return lambdaExpr.resolve(markers, context);
}
use of dyvilx.tools.compiler.ast.expression.LambdaExpr in project Dyvil by Dyvil.
the class StatementListParser method parse.
@Override
public void parse(IParserManager pm, IToken token) {
final int type = token.type();
if (type == BaseSymbols.CLOSE_CURLY_BRACKET) {
this.end(pm);
return;
}
if (type == Tokens.EOF) {
this.end(pm);
pm.report(token, "statement_list.close_brace");
return;
}
switch(this.mode) {
case OPEN_BRACKET:
{
final IToken next = token.next();
final IToken lambdaArrow = this.findLambdaArrow(next);
if (lambdaArrow != null) {
this.lambdaExpr = new LambdaExpr(lambdaArrow.raw());
this.lambdaExpr.setValue(this.statementList = new StatementList(token));
if (next == lambdaArrow) {
// { ->
// { =>
this.mode = LAMBDA_TYPE_ARROW;
return;
}
if (next.type() == BaseSymbols.OPEN_PARENTHESIS) {
// { ( ... ) =>
// { ( ... ) ->
pm.skip();
pm.pushParser(new ParameterListParser(this.lambdaExpr));
this.mode = LAMBDA_PARAMETERS_END;
return;
}
// { ... ->
// { ... =>
pm.pushParser(new ParameterListParser(this.lambdaExpr).withFlags(LAMBDA_ARROW_END));
this.mode = LAMBDA_TYPE_ARROW;
return;
}
// { ...
this.statementList = this.closure ? new Closure(token) : new StatementList(token);
this.mode = EXPRESSION;
if (type != BaseSymbols.OPEN_CURLY_BRACKET) {
pm.report(token, "statement_list.open_brace");
pm.reparse();
}
return;
}
case LAMBDA_PARAMETERS_END:
this.mode = LAMBDA_TYPE_ARROW;
if (type != BaseSymbols.CLOSE_PARENTHESIS) {
pm.report(token, "statement_list.lambda.close_paren");
}
return;
case LAMBDA_TYPE_ARROW:
if (type == DyvilSymbols.ARROW_RIGHT) {
pm.pushParser(LambdaOrTupleParser.returnTypeParser(this.lambdaExpr));
this.mode = LAMBDA_RETURN_ARROW;
return;
}
// Fallthrough
case LAMBDA_RETURN_ARROW:
if (type != DyvilSymbols.DOUBLE_ARROW_RIGHT) {
pm.report(token, "statement_list.lambda.arrow");
return;
}
this.mode = EXPRESSION;
return;
case EXPRESSION:
switch(type) {
case BaseSymbols.SEMICOLON:
case BaseSymbols.COMMA:
return;
case DyvilKeywords.LABEL:
this.mode = LABEL_NAME;
return;
}
this.mode = SEPARATOR;
final MemberParser<IVariable> parser = new MemberParser<>(this).withFlags(MemberParser.NO_FIELD_PROPERTIES);
if (this.tryParserManager.tryParse(pm, parser, token, EXIT_ON_ROOT)) {
return;
}
pm.pushParser(new ExpressionParser(this));
return;
case LABEL_NAME:
if (Tokens.isIdentifier(type)) {
this.label = token.nameValue();
this.mode = LABEL_END;
return;
}
this.mode = EXPRESSION;
if (type != BaseSymbols.COLON) {
pm.reparse();
}
pm.report(token, "statement_list.label.name");
return;
case LABEL_END:
switch(type) {
case BaseSymbols.COLON:
case BaseSymbols.SEMICOLON:
this.mode = EXPRESSION;
return;
}
this.mode = EXPRESSION;
pm.reparse();
pm.report(SourcePosition.between(token, token.next()), "statement_list.label.separator");
return;
case SEPARATOR:
this.mode = EXPRESSION;
switch(type) {
case BaseSymbols.SEMICOLON:
case BaseSymbols.COMMA:
return;
}
pm.report(token, "statement_list.semicolon");
}
}
use of dyvilx.tools.compiler.ast.expression.LambdaExpr in project Dyvil by Dyvil.
the class LambdaOrTupleParser method parse.
@Override
public void parse(IParserManager pm, IToken token) {
final int type = token.type();
switch(this.mode) {
case OPEN_PARENTHESIS:
// ( ...
// ^
/*
* The new version of this parser tries to find the matching closing parenthesis instead of try-parsing the
* expression. If it finds that parenthesis token and the next token is a lambda arrow, we can assume that
* the expression is a lambda expression. Thus, we directly push a Parameter List Parser that may also
* produce syntax errors.
*/
final IToken closeParen = BracketMatcher.findMatch(token);
if (closeParen != null) {
final IToken next = closeParen.next();
final int nextType = next.type();
if (nextType == DyvilSymbols.ARROW_RIGHT || nextType == DyvilSymbols.DOUBLE_ARROW_RIGHT) {
// ( ... ) =>
// ( ... ) ->
// token closeParen next
final LambdaExpr lambdaExpr = new LambdaExpr(next);
pm.pushParser(new ParameterListParser(lambdaExpr));
this.value = lambdaExpr;
this.mode = PARAMETERS_END;
return;
}
}
// Fallthrough
case TUPLE:
// ( ... )
final TupleLikeExpr tupleExpr = new TupleLikeExpr(token);
pm.pushParser(new ArgumentListParser(tupleExpr));
this.value = tupleExpr;
this.mode = TUPLE_END;
return;
case TUPLE_END:
this.value.expandPosition(token);
this.consumer.setValue(this.value);
pm.popParser();
if (type != BaseSymbols.CLOSE_PARENTHESIS) {
pm.reparse();
pm.report(token, "tuple.close_paren");
}
return;
case PARAMETERS_END:
this.mode = TYPE_ARROW;
if (type != BaseSymbols.CLOSE_PARENTHESIS) {
pm.reparse();
pm.report(token, "lambda.close_paren");
}
return;
case SINGLE_PARAMETER:
if (Tokens.isIdentifier(type)) {
final LambdaExpr lambdaExpr = new LambdaExpr(token.next());
final IParameter parameter = lambdaExpr.createParameter(token.raw(), token.nameValue(), Types.UNKNOWN, new AttributeList());
lambdaExpr.getParameters().add(parameter);
this.value = lambdaExpr;
this.mode = TYPE_ARROW;
return;
}
// Fallthrough
case TYPE_ARROW:
if (this.value == null) {
this.value = new LambdaExpr(token.raw());
}
if (type == DyvilSymbols.ARROW_RIGHT) {
pm.pushParser(returnTypeParser((LambdaExpr) this.value));
this.mode = RETURN_ARROW;
return;
}
// Fallthrough
case RETURN_ARROW:
pm.pushParser(new ExpressionParser(((LambdaExpr) this.value)));
this.mode = END;
if (type != DyvilSymbols.DOUBLE_ARROW_RIGHT) {
pm.reparse();
pm.report(token, "lambda.arrow");
}
return;
case END:
pm.popParser(true);
this.consumer.setValue(this.value);
}
}
use of dyvilx.tools.compiler.ast.expression.LambdaExpr in project Dyvil by Dyvil.
the class Closure method withType.
@Override
public IValue withType(IType type, ITypeContext typeContext, MarkerList markers, IContext context) {
if (this.resolved) {
return super.withType(type, typeContext, markers, context);
}
final IMethod functionalMethod = type.getFunctionalMethod();
if (functionalMethod == null) {
return null;
}
final ParameterList parameterList = functionalMethod.getParameters();
final int parameterCount = parameterList.size();
final IParameter[] parameters = new IParameter[parameterCount];
for (int i = 0; i < parameterCount; i++) {
parameters[i] = new CodeParameter(null, this.position, Name.fromRaw("$" + i), Types.UNKNOWN);
}
final LambdaType functionType = type.extract(LambdaType.class);
if (functionType != null && functionType.isExtension() && parameterCount > 0) {
this.implicitValue = new FieldAccess(parameters[0]);
}
final LambdaExpr lambdaExpr = new LambdaExpr(this.position, parameters, parameterCount);
lambdaExpr.setValue(this);
this.resolved = true;
context = context.push(this);
final IValue typedLambda = lambdaExpr.withType(type, typeContext, markers, context);
context.pop();
return typedLambda;
}
Aggregations