use of dyvilx.tools.compiler.ast.statement.StatementList in project Dyvil by Dyvil.
the class ClassMetadata method createDefaultConstructor.
private CodeConstructor createDefaultConstructor() {
// init(classParams...)
final SourcePosition position = this.theClass.position();
final AttributeList attributes = this.theClass.getConstructorAttributes();
attributes.addFlag(Modifiers.GENERATED);
final CodeConstructor constructor = new CodeConstructor(this.theClass, attributes);
constructor.setPosition(position);
this.copyClassParameters(constructor);
// : super(superParams...)
final IType superType = this.theClass.getSuperType();
if (superType != null) {
// Generate the constructor body
ArgumentList arguments = this.theClass.getSuperConstructorArguments();
if (arguments == null) {
arguments = ArgumentList.empty();
}
final InitializerCall init = new InitializerCall(this.theClass.getPosition(), true, arguments, superType);
constructor.setInitializer(init);
}
// { this.classParams... = classParams... }
final ParameterList classParams = this.theClass.getParameters();
final StatementList ctorBody = new StatementList();
final ParameterList ctorParams = constructor.getParameters();
// j is the counter for class parameters, as there may be leading synthetic constructor parameters
for (int i = 0, j = 0, count = ctorParams.size(); i < count; i++) {
final IParameter ctorParam = ctorParams.get(i);
if (ctorParam.hasModifier(Modifiers.SYNTHETIC)) {
continue;
}
final IParameter classParam = classParams.get(j++);
if (classParam.hasModifier(Modifiers.OVERRIDE)) {
continue;
}
final IValue receiver = new ThisExpr(this.theClass);
final FieldAccess access = new FieldAccess(ctorParam);
final FieldAssignment assignment = new FieldAssignment(position, receiver, classParam, access);
ctorBody.add(assignment);
}
constructor.setValue(ctorBody);
return constructor;
}
use of dyvilx.tools.compiler.ast.statement.StatementList 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.statement.StatementList in project Dyvil by Dyvil.
the class SideEffectHelper method processValue.
public IValue processValue(IValue value) {
if (value == null || !value.hasSideEffects()) {
return value;
}
if (this.statementList == null) {
this.statementList = new StatementList();
}
final Variable variable = new Variable(value.getPosition(), Name.fromRaw("sideEffect$" + this.registered), value.getType());
variable.setValue(value);
this.statementList.add(new VariableStatement(variable));
this.statementList.addVariable(variable);
this.registered++;
return new FieldAccess(value.getPosition(), null, variable);
}
use of dyvilx.tools.compiler.ast.statement.StatementList in project Dyvil by Dyvil.
the class ForDirectiveParser method parse.
@Override
public void parse(IParserManager pm, IToken token) {
// #for (IDENTIFIER <- EXPRESSION) {BLOCK}
final int type = token.type();
switch(this.mode) {
case FOR:
assert type == GenSrcSymbols.FOR;
this.mode = OPEN_PAREN;
this.directive = new ForEachDirective(token.raw(), null);
return;
case OPEN_PAREN:
if (type != BaseSymbols.OPEN_PARENTHESIS) {
pm.report(token, "for.open_paren");
this.list.add(this.directive);
pm.popParser(true);
return;
}
this.mode = VAR_NAME;
return;
case VAR_NAME:
if (type == Tokens.LETTER_IDENTIFIER) {
this.directive.setVariable(new Variable(token.raw(), token.nameValue(), Types.UNKNOWN));
this.mode = TYPE_ASCRIPTION;
return;
}
pm.report(token, "for.identifier");
if (type == BaseSymbols.CLOSE_PARENTHESIS) {
this.mode = BODY;
}
return;
case TYPE_ASCRIPTION:
if (type == BaseSymbols.COLON) {
pm.pushParser(new TypeParser(this.directive.getVariable()));
this.mode = ARROW;
return;
}
// Fallthrough
case ARROW:
if (type != GenSrcSymbols.ARROW_LEFT) {
pm.reparse();
pm.report(token, "for.arrow_left");
}
pm.pushParser(new ExpressionParser(this.directive.getVariable()));
this.mode = CLOSE_PAREN;
return;
case CLOSE_PAREN:
if (type != BaseSymbols.CLOSE_PARENTHESIS) {
pm.report(token, "for.close_paren");
return;
}
this.mode = BODY;
return;
case BODY:
if (type != BaseSymbols.OPEN_CURLY_BRACKET) {
pm.report(token, "for.open_brace");
this.list.add(this.directive);
pm.popParser(true);
return;
}
final StatementList body = new StatementList();
pm.pushParser(new BlockParser(body));
this.directive.setAction(body);
this.mode = BODY_END;
return;
case BODY_END:
if (type != BaseSymbols.CLOSE_CURLY_BRACKET) {
pm.report(token, "for.close_brace");
}
this.list.add(this.directive);
pm.popParser();
}
}
use of dyvilx.tools.compiler.ast.statement.StatementList in project Dyvil by Dyvil.
the class IfDirectiveParser method parse.
@Override
public void parse(IParserManager pm, IToken token) {
// #if (EXPRESSION) {BLOCK}
// #if (EXPRESSION) {BLOCK} #else {BLOCK}
final int type = token.type();
switch(this.mode) {
case IF:
assert type == GenSrcSymbols.IF;
this.directive = new IfDirective(token.raw());
this.mode = OPEN_PAREN;
return;
case OPEN_PAREN:
if (type != BaseSymbols.OPEN_PARENTHESIS) {
pm.report(token, "if.open_paren");
this.list.add(this.directive);
pm.popParser(true);
return;
}
pm.pushParser(new ExpressionParser(this.directive::setCondition));
this.mode = CLOSE_PAREN;
return;
case CLOSE_PAREN:
if (type != BaseSymbols.CLOSE_PARENTHESIS) {
pm.report(token, "if.close_paren");
return;
}
this.mode = THEN_BODY;
return;
case THEN_BODY:
if (type != BaseSymbols.OPEN_CURLY_BRACKET) {
pm.report(token, "if.open_brace");
this.list.add(this.directive);
pm.popParser(true);
return;
}
final StatementList thenBlock = new StatementList();
pm.pushParser(new BlockParser(thenBlock));
this.directive.setThen(thenBlock);
this.mode = THEN_BODY_END;
return;
case THEN_BODY_END:
if (type != BaseSymbols.CLOSE_CURLY_BRACKET) {
pm.report(token, "if.close_brace");
this.list.add(this.directive);
pm.popParser();
return;
}
this.mode = ELSE;
return;
case ELSE:
if (type == Tokens.STRING && isBlank(token.stringValue()) && isHashElse(token.next())) {
// ignore empty whitespace between } and #else
// skip the '#' and 'else'
pm.skip(2);
this.mode = ELSE_BODY;
return;
}
if (isHashElse(token)) {
// skip the 'else'
pm.skip();
this.mode = ELSE_BODY;
return;
}
this.list.add(this.directive);
pm.popParser(true);
return;
case ELSE_BODY:
if (type != BaseSymbols.OPEN_CURLY_BRACKET) {
pm.report(token, "if.else.open_brace");
this.list.add(this.directive);
pm.popParser(true);
return;
}
final StatementList elseBlock = new StatementList();
pm.pushParser(new BlockParser(elseBlock));
this.directive.setElse(elseBlock);
this.mode = ELSE_BODY_END;
return;
case ELSE_BODY_END:
if (type != BaseSymbols.CLOSE_CURLY_BRACKET) {
pm.report(token, "if.else.close_brace");
}
this.list.add(this.directive);
pm.popParser();
}
}
Aggregations