This commit is contained in:
Johanna Stuber 2021-01-30 13:14:03 +01:00
commit b961a7c5ca
3 changed files with 59 additions and 29 deletions

View File

@ -50,7 +50,7 @@ public class TypeInferer implements TypeInfererInterface {
return; return;
} }
List<Substitution> substitutions = unification.getSubstitutions().getValue(); List<Substitution> substitutions = unification.getSubstitutions().unwrap();
typeInfResult = Optional.of(new TypeInferenceResult(substitutions, tree.getFirstTypeVariable())); typeInfResult = Optional.of(new TypeInferenceResult(substitutions, tree.getFirstTypeVariable()));
} }

View File

@ -25,7 +25,7 @@ public class LambdaParser {
* When calling a parseX method, token is the first token of X * When calling a parseX method, token is the first token of X
* (as opposed to the last token of the previous construct). * (as opposed to the last token of the previous construct).
*/ */
private Token token; private Token token = new Token(TokenType.EOF, "", -1);
private static final Set<TokenType> ATOM_START_TOKENS private static final Set<TokenType> ATOM_START_TOKENS
= EnumSet.of(TokenType.VARIABLE, TokenType.NUMBER, TokenType.TRUE, = EnumSet.of(TokenType.VARIABLE, TokenType.NUMBER, TokenType.TRUE,
@ -97,10 +97,16 @@ public class LambdaParser {
switch (token.getType()) { switch (token.getType()) {
case LAMBDA: case LAMBDA:
Result<AbsTerm, ParseError> abs = parseAbstraction(); Result<AbsTerm, ParseError> abs = parseAbstraction();
return new Result<>(abs.unwrap(), abs.getError()); if (abs.isError()) {
return new Result<>(abs);
}
return new Result<>(abs.unwrap());
case LET: case LET:
Result<LetTerm, ParseError> let = parseLet(); Result<LetTerm, ParseError> let = parseLet();
return new Result<>(let.unwrap(), let.getError()); if (let.isError()) {
return new Result<>(let);
}
return new Result<>(let.unwrap());
case EOF: case EOF:
return new Result<>(null, ParseError.TOO_FEW_TOKENS); return new Result<>(null, ParseError.TOO_FEW_TOKENS);
default: default:
@ -111,12 +117,17 @@ public class LambdaParser {
private Result<AbsTerm, ParseError> parseAbstraction() { private Result<AbsTerm, ParseError> parseAbstraction() {
nextToken(); nextToken();
Result<VarTerm, ParseError> var = parseVar(); Result<VarTerm, ParseError> var = parseVar();
if (var.isError()) {
return new Result<>(var);
}
Optional<ParseError> next = expect(TokenType.DOT); Optional<ParseError> next = expect(TokenType.DOT);
if (next.isPresent()) { if (next.isPresent()) {
return new Result<>(null, next.get()); return new Result<>(null, next.get());
} }
Result<LambdaTerm, ParseError> body = parseTerm(false); Result<LambdaTerm, ParseError> body = parseTerm(false);
// TODO: Fehlerbehandlung if (body.isError()) {
return new Result<>(body);
}
return new Result<>(new AbsTerm(var.unwrap(), body.unwrap())); return new Result<>(new AbsTerm(var.unwrap(), body.unwrap()));
} }
@ -140,23 +151,31 @@ public class LambdaParser {
} }
private Result<LetTerm, ParseError> parseLet() { private Result<LetTerm, ParseError> parseLet() {
// TODO: Fehlerbehandlung
Optional<ParseError> error = expect(TokenType.LET); Optional<ParseError> error = expect(TokenType.LET);
if (error.isPresent()) { if (error.isPresent()) {
return new Result<>(null, error.get()); return new Result<>(null, error.get());
} }
VarTerm var = parseVar().unwrap(); Result<VarTerm, ParseError> var = parseVar();
if (var.isError()) {
return new Result<>(var);
}
error = expect(TokenType.EQ); error = expect(TokenType.EQ);
if (error.isPresent()) { if (error.isPresent()) {
return new Result<>(null, error.get()); return new Result<>(null, error.get());
} }
LambdaTerm def = parseTerm(false).unwrap(); Result<LambdaTerm, ParseError> def = parseTerm(false);
if (def.isError()) {
return new Result<>(def);
}
error = expect(TokenType.IN); error = expect(TokenType.IN);
if (error.isPresent()) { if (error.isPresent()) {
return new Result<>(null, error.get()); return new Result<>(null, error.get());
} }
LambdaTerm body = parseTerm(false).unwrap(); Result<LambdaTerm, ParseError> body = parseTerm(false);
return new Result<>(new LetTerm(var, def, body)); if (body.isError()) {
return new Result<>(body);
}
return new Result<>(new LetTerm(var.unwrap(), def.unwrap(), body.unwrap()));
} }
/** /**
@ -167,7 +186,10 @@ public class LambdaParser {
switch (token.getType()) { switch (token.getType()) {
case VARIABLE: case VARIABLE:
Result<VarTerm, ParseError> var = parseVar(); Result<VarTerm, ParseError> var = parseVar();
return new Result<>(var.unwrap(), var.getError()); if (var.isError()) {
return new Result<>(var);
}
return new Result<>(var.unwrap());
case NUMBER: case NUMBER:
String number = token.getText(); String number = token.getText();
int n; int n;
@ -176,18 +198,30 @@ public class LambdaParser {
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
return new Result<>(null, ParseError.UNEXPECTED_CHARACTER.withToken(token)); return new Result<>(null, ParseError.UNEXPECTED_CHARACTER.withToken(token));
} }
nextToken(); Optional<ParseError> error = nextToken();
if (error.isPresent()) {
return new Result<>(null, error.get());
}
return new Result<>(new IntegerTerm(n)); return new Result<>(new IntegerTerm(n));
case TRUE: case TRUE:
case FALSE: case FALSE:
String boolText = token.getText(); String boolText = token.getText();
boolean b = Boolean.parseBoolean(boolText); boolean b = Boolean.parseBoolean(boolText);
nextToken(); error = nextToken();
if (error.isPresent()) {
return new Result<>(null, error.get());
}
return new Result<>(new BooleanTerm(b)); return new Result<>(new BooleanTerm(b));
default: default:
expect(TokenType.LP); error = expect(TokenType.LP);
if (error.isPresent()) {
return new Result<>(null, error.get());
}
Result<LambdaTerm, ParseError> term = parseTerm(false); Result<LambdaTerm, ParseError> term = parseTerm(false);
expect(TokenType.RP); error = expect(TokenType.RP);
if (error.isPresent()) {
return new Result<>(null, error.get());
}
return term; return term;
} }
} }

View File

@ -20,6 +20,16 @@ public class Result<T, E> {
this.error = null; this.error = null;
} }
/**
* Creates a new result by copying another one.
*
* @param other the result
*/
public Result(Result other) {
this.value = (T) other.value;
this.error = (E) other.error;
}
/** /**
* Creates a new result containing the given value or error. * Creates a new result containing the given value or error.
* Only one of the parameters may be non-null. * Only one of the parameters may be non-null.
@ -77,18 +87,4 @@ public class Result<T, E> {
} }
return error; return error;
} }
/**
* @return the value contained, or null
*/
public T getValue() {
return value;
}
/**
* @return the error contained, or null
*/
public E getError() {
return error;
}
} }