Compare commits
3 Commits
c05aa302a4
...
3d88a704ae
Author | SHA1 | Date | |
---|---|---|---|
3d88a704ae | |||
30288731d3 | |||
f7d135cdd6 |
@ -17,6 +17,8 @@ public class Main {
|
||||
TestMalicious malicious = new TestMalicious();
|
||||
TestLoop loop = new TestLoop();
|
||||
TestMethodOverload overload = new TestMethodOverload();
|
||||
TestShenanigance shenanigance = new TestShenanigance();
|
||||
TestOptionalParameter optionalParameter = new TestOptionalParameter();
|
||||
|
||||
// constructing a basic class works
|
||||
assert empty != null;
|
||||
@ -35,6 +37,7 @@ public class Main {
|
||||
// self-referencing methods work.
|
||||
assert recursion.fibonacci(15) == 610;
|
||||
assert loop.factorial(5) == 120;
|
||||
assert loop.weirdFor() == 5;
|
||||
// methods with the same name but different parameters work
|
||||
assert overload.MethodOverload() == 42;
|
||||
assert overload.MethodOverload(15) == 42 + 15;
|
||||
@ -48,5 +51,14 @@ public class Main {
|
||||
{
|
||||
assert malicious.cursedFormatting(i) == i;
|
||||
}
|
||||
// other syntactic sugar
|
||||
assert shenanigance.testAssignment() == 5;
|
||||
assert shenanigance.divEqual() == 234_343_000 / 4;
|
||||
assert shenanigance.testIf(5);
|
||||
// optional parameters
|
||||
assert optionalParameter.oneOptional() == 1;
|
||||
assert optionalParameter.oneOptional(2) == 2;
|
||||
assert optionalParameter.normalAndOptional(1) == 6;
|
||||
assert optionalParameter.normalAndOptional(1, 0, 0) == 1;
|
||||
}
|
||||
}
|
||||
|
@ -9,4 +9,11 @@ public class TestLoop {
|
||||
|
||||
return tally;
|
||||
}
|
||||
|
||||
int weirdFor() {
|
||||
int k = 0;
|
||||
for (; k < 5; k++) {
|
||||
}
|
||||
return k;
|
||||
}
|
||||
}
|
||||
|
10
Test/JavaSources/TestOptionalParameter.java
Normal file
10
Test/JavaSources/TestOptionalParameter.java
Normal file
@ -0,0 +1,10 @@
|
||||
class TestOptionalParameter {
|
||||
|
||||
int oneOptional(int p = 1) {
|
||||
return p;
|
||||
}
|
||||
|
||||
int normalAndOptional(int a, int b = 2, int c = 3) {
|
||||
return a + b + c;
|
||||
}
|
||||
}
|
25
Test/JavaSources/TestShenanigance.java
Normal file
25
Test/JavaSources/TestShenanigance.java
Normal file
@ -0,0 +1,25 @@
|
||||
class TestShenanigance {
|
||||
|
||||
int testAssignment() {
|
||||
int x = 1;
|
||||
int y = x = 5;
|
||||
return y;
|
||||
}
|
||||
|
||||
int divEqual() {
|
||||
int x = 234_343_000;
|
||||
x /= 4;
|
||||
return x;
|
||||
}
|
||||
|
||||
boolean testIf(int x) {
|
||||
if (true && x < 8) {
|
||||
char f = 'c';
|
||||
return f > x ;
|
||||
}
|
||||
ifn't {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Binary file not shown.
@ -1,5 +1,5 @@
|
||||
{
|
||||
module Parser.JavaParser (parse, parseStatement, parseExpression) where
|
||||
module Parser.JavaParser (parse, parseStatement, parseExpression, parseMethod) where
|
||||
import Ast
|
||||
import Parser.Lexer
|
||||
}
|
||||
@ -7,6 +7,7 @@ import Parser.Lexer
|
||||
%name parse
|
||||
%name parseStatement statement
|
||||
%name parseExpression expression
|
||||
%name parseMethod classbodydeclarations
|
||||
%tokentype { Token }
|
||||
%error { parseError }
|
||||
%errorhandlertype explist
|
||||
@ -104,13 +105,13 @@ modifiers : modifier { }
|
||||
classbodydeclarations : classbodydeclaration {
|
||||
case $1 of
|
||||
ConstructorDecl constructor -> ([constructor], [], [])
|
||||
MethodDecl method -> ([], [method], [])
|
||||
MethodDecl method -> ([], (convertMethodDeclarationWithOptionals method), [])
|
||||
FieldDecls fields -> ([], [], fields)
|
||||
}
|
||||
| classbodydeclarations classbodydeclaration {
|
||||
case ($1, $2) of
|
||||
((constructors, methods, fields), ConstructorDecl constructor) -> ((constructors ++ [constructor]), methods, fields)
|
||||
((constructors, methods, fields), MethodDecl method) -> (constructors, (methods ++ [method]), fields)
|
||||
((constructors, methods, fields), MethodDecl method) -> (constructors, (methods ++ (convertMethodDeclarationWithOptionals method)), fields)
|
||||
((constructors, methods, fields), FieldDecls newFields) -> (constructors, methods, (fields ++ newFields))
|
||||
}
|
||||
|
||||
@ -136,7 +137,7 @@ constructordeclaration : constructordeclarator constructorbody { case $1 of (ide
|
||||
fielddeclaration : type variabledeclarators SEMICOLON { FieldDecls $ map (convertDeclarator $1) $2 }
|
||||
| modifiers type variabledeclarators SEMICOLON { FieldDecls $ map (convertDeclarator $2) $3 }
|
||||
|
||||
methoddeclaration : methodheader methodbody { case $1 of (returnType, (name, parameters)) -> MethodDecl (MethodDeclaration returnType name parameters $2) }
|
||||
methoddeclaration : methodheader methodbody { case $1 of (returnType, (name, (parameters, optionalparameters))) -> MethodDecl (MethodDeclarationWithOptionals returnType name parameters optionalparameters $2) }
|
||||
|
||||
block : LBRACKET RBRACKET { Block [] }
|
||||
| LBRACKET blockstatements RBRACKET { Block $2 }
|
||||
@ -166,6 +167,10 @@ methodbody : block { $1 }
|
||||
blockstatements : blockstatement { $1 }
|
||||
| blockstatements blockstatement { $1 ++ $2}
|
||||
|
||||
formalandoptionalparameterlist : formalparameterlist { ($1, []) }
|
||||
| formalparameterlist COMMA optionalparameterlist { ($1, $3) }
|
||||
| optionalparameterlist { ([], $1) }
|
||||
|
||||
formalparameterlist : formalparameter { [$1] }
|
||||
| formalparameterlist COMMA formalparameter { $1 ++ [$3] }
|
||||
|
||||
@ -175,8 +180,13 @@ explicitconstructorinvocation : THIS LBRACE RBRACE SEMICOLON { }
|
||||
classtypelist : classtype { }
|
||||
| classtypelist COMMA classtype { }
|
||||
|
||||
methoddeclarator : IDENTIFIER LBRACE RBRACE { ($1, []) }
|
||||
| IDENTIFIER LBRACE formalparameterlist RBRACE { ($1, $3) }
|
||||
methoddeclarator : IDENTIFIER LBRACE RBRACE { ($1, ([], [])) }
|
||||
| IDENTIFIER LBRACE formalandoptionalparameterlist RBRACE { ($1, $3) }
|
||||
|
||||
optionalparameterlist : optionalparameter { [$1] }
|
||||
| optionalparameterlist COMMA optionalparameter { $1 ++ [$3] }
|
||||
|
||||
optionalparameter : type variabledeclaratorid ASSIGN variableinitializer { OptionalParameter $1 $2 $4 }
|
||||
|
||||
primitivetype : BOOLEAN { "boolean" }
|
||||
| numerictype { $1 }
|
||||
@ -386,9 +396,9 @@ multiplicativeexpression : unaryexpression { $1 }
|
||||
|
||||
{
|
||||
|
||||
data MemberDeclaration = MethodDecl MethodDeclaration
|
||||
data MemberDeclaration = MethodDecl MethodDeclarationWithOptionals
|
||||
| ConstructorDecl ConstructorDeclaration
|
||||
| FieldDecls [VariableDeclaration]
|
||||
| FieldDecls [VariableDeclaration] deriving (Show)
|
||||
|
||||
data Declarator = Declarator Identifier (Maybe Expression)
|
||||
|
||||
@ -399,6 +409,22 @@ extractFunctionName :: Expression -> (Expression, Identifier)
|
||||
extractFunctionName (BinaryOperation NameResolution exp (Reference functionname)) = (exp, functionname)
|
||||
extractFunctionName (Reference functionname) = ((Reference "this"), functionname)
|
||||
|
||||
data OptionalParameter = OptionalParameter DataType Identifier Expression deriving (Show)
|
||||
data MethodDeclarationWithOptionals = MethodDeclarationWithOptionals DataType Identifier [ParameterDeclaration] [OptionalParameter] Statement deriving (Show)
|
||||
convertMethodDeclarationWithOptionals :: MethodDeclarationWithOptionals -> [MethodDeclaration]
|
||||
convertMethodDeclarationWithOptionals (MethodDeclarationWithOptionals returnType id param [] stmt) = [MethodDeclaration returnType id param stmt]
|
||||
convertMethodDeclarationWithOptionals (MethodDeclarationWithOptionals returnType id param (opt : optRest) stmt) = generateHelperMethod returnType id param opt : convertMethodDeclarationWithOptionals (generateBaseMethod returnType id param opt optRest stmt)
|
||||
convertOptionalParameter :: OptionalParameter -> ParameterDeclaration
|
||||
convertOptionalParameter (OptionalParameter dtype id exp) = ParameterDeclaration dtype id
|
||||
generateHelperMethod :: DataType -> Identifier -> [ParameterDeclaration] -> OptionalParameter -> MethodDeclaration
|
||||
generateHelperMethod returnType methodName params (OptionalParameter dtype id exp) =
|
||||
let references = ((map (\(ParameterDeclaration paramType ident) -> (Reference ident)) params) ++ [exp])
|
||||
methodcall = (MethodCall (Reference "this") methodName references)
|
||||
lastStatement = if returnType == "void" then StatementExpressionStatement methodcall else Return $ Just $ StatementExpressionExpression methodcall
|
||||
in MethodDeclaration returnType methodName params $ Block [lastStatement]
|
||||
generateBaseMethod :: DataType -> Identifier -> [ParameterDeclaration] -> OptionalParameter -> [OptionalParameter] -> Statement -> MethodDeclarationWithOptionals
|
||||
generateBaseMethod returnType methodName params (OptionalParameter dtype id exp) optRest stmt = MethodDeclarationWithOptionals returnType methodName (params ++ [ParameterDeclaration dtype id]) optRest stmt
|
||||
|
||||
parseError :: ([Token], [String]) -> a
|
||||
parseError (errortoken, expected) = error ("parse error on token: " ++ show errortoken ++ "\nexpected one of: " ++ show expected)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user