├── .gitignore
├── .travis.yml
├── run.sh
├── clean.sh
├── make.sh
├── CONTRIBUTING.md
├── src
└── com
│ └── google
│ └── codeu
│ └── mathlang
│ ├── testing
│ ├── TestCriteria.java
│ ├── TestListener.java
│ ├── TestNoteFunction.java
│ ├── TestPrintFunction.java
│ ├── TestLetFunction.java
│ ├── CallTable.java
│ └── Tester.java
│ ├── core
│ ├── Variable.java
│ ├── Function.java
│ ├── tokens
│ │ ├── Token.java
│ │ ├── NumberToken.java
│ │ ├── NameToken.java
│ │ ├── StringToken.java
│ │ └── SymbolToken.java
│ └── State.java
│ ├── functions
│ ├── operations
│ │ ├── Operation.java
│ │ ├── AddOperation.java
│ │ └── SubtractOperation.java
│ ├── NoteFunction.java
│ ├── PrintFunction.java
│ └── LetFunction.java
│ ├── parsing
│ ├── TokenReader.java
│ ├── StatementBuilder.java
│ └── StatementReader.java
│ ├── impl
│ └── MyTokenReader.java
│ └── Test.java
├── README.md
└── LICENSE
/.gitignore:
--------------------------------------------------------------------------------
1 | bin
2 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: java
2 |
3 | sudo: false
4 |
5 | jdk:
6 | - openjdk7
7 | - oraclejdk8
8 |
9 | os:
10 | - linux
11 |
12 |
13 | script:
14 | - ./clean.sh
15 | - ./build.sh
16 |
--------------------------------------------------------------------------------
/run.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Copyright 2017 Google Inc.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | set -e
18 |
19 | java -classpath bin com.google.codeu.mathlang.Test
20 |
--------------------------------------------------------------------------------
/clean.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Copyright 2017 Google Inc.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | set -e
18 |
19 | if [ -d './bin' ] ; then
20 | rm -rf $(find './bin' -maxdepth 1 -mindepth 1)
21 | fi
22 |
--------------------------------------------------------------------------------
/make.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Copyright 2017 Google Inc.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | set -e
18 |
19 | rm -rf bin
20 | mkdir -p bin
21 | javac -Xlint -classpath bin -d bin -sourcepath src $(find src -name *.java)
22 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # How to contribute
2 |
3 | We'd love to accept your patches and contributions to this project. There are
4 | just a few small guidelines you need to follow.
5 |
6 | ## Contributor License Agreement
7 |
8 | Contributions to this project must be accompanied by a Contributor License
9 | Agreement. You (or your employer) retain the copyright to your contribution,
10 | this simply gives us permission to use and redistribute your contributions as
11 | part of the project. Head over to to see
12 | your current agreements on file or to sign a new one.
13 |
14 | You generally only need to submit a CLA once, so if you've already submitted one
15 | (even if it was for a different project), you probably don't need to do it
16 | again.
17 |
18 | ## Code reviews
19 |
20 | All submissions, including submissions by project members, require review. We
21 | use GitHub pull requests for this purpose. Consult
22 | [GitHub Help](https://help.github.com/articles/about-pull-requests/) for more
23 | information on using pull requests.
24 |
--------------------------------------------------------------------------------
/src/com/google/codeu/mathlang/testing/TestCriteria.java:
--------------------------------------------------------------------------------
1 | // Copyright 2017 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.codeu.mathlang.testing;
16 |
17 | // TEST CRITERIA
18 | //
19 | // This interface verifies a call table after a test has completed.
20 | public interface TestCriteria {
21 |
22 | // ON TEST END
23 | //
24 | // This method performs a final check on the call table, to verify that the
25 | // the call table is clean. If it is not clean, throw an exception, which will
26 | // cause the test to fail.
27 | void onTestEnd(CallTable calls) throws Exception;
28 | }
29 |
--------------------------------------------------------------------------------
/src/com/google/codeu/mathlang/core/Variable.java:
--------------------------------------------------------------------------------
1 | // Copyright 2017 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.codeu.mathlang.core;
16 |
17 | // VARIABLE
18 | //
19 | // This class writes the value of a variable. This is done to allow
20 | // a variable to be passed around by reference.
21 | public final class Variable {
22 |
23 | private double value = 0;
24 |
25 | // READ
26 | //
27 | // Read the value that this variable holds.
28 | public double read() {
29 | return value;
30 | }
31 |
32 | // WRITE
33 | //
34 | // Write a new value to the variable, replacing the previous value held by the variable.
35 | public void write(double value) {
36 | this.value = value;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/com/google/codeu/mathlang/testing/TestListener.java:
--------------------------------------------------------------------------------
1 | // Copyright 2017 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.codeu.mathlang.testing;
16 |
17 | // TEST LISTENER
18 | //
19 | // This interface defines the callbacks that |Tester| will use to communicate
20 | // events that happen while running through tests.
21 | public interface TestListener {
22 |
23 | // ON TEST START
24 | //
25 | // Called when a test first starts.
26 | void onTestStart(String testName);
27 |
28 | // ON PASS
29 | //
30 | // Called when a test completed successfully.
31 | void onPass();
32 |
33 | // ON FAIL
34 | //
35 | // Called when a test fails to complete successfully. The exception
36 | // passed to the method is the original exception thrown during
37 | // execution.
38 | void onFail(Exception ex);
39 | }
40 |
--------------------------------------------------------------------------------
/src/com/google/codeu/mathlang/core/Function.java:
--------------------------------------------------------------------------------
1 | // Copyright 2017 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.codeu.mathlang.core;
16 |
17 | import com.google.codeu.mathlang.core.tokens.Token;
18 |
19 | // FUNCTION
20 | //
21 | // This interface is for a single functional unit of work defined by the
22 | // paramters passed to it as an array of tokens. Functions should avoid
23 | // carrying internal state.
24 | public interface Function {
25 |
26 | // RUN
27 | //
28 | // This method is called when the there is a statement ready for it. The first
29 | // token will always be the identifier of the function. The function should
30 | // ignore this token. If any other token does not meet the expectations of the
31 | // function, an exception should be thrown and execution will be stopped.
32 | void run(Token[] statement) throws Exception;
33 | }
34 |
--------------------------------------------------------------------------------
/src/com/google/codeu/mathlang/core/tokens/Token.java:
--------------------------------------------------------------------------------
1 | // Copyright 2017 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.codeu.mathlang.core.tokens;
16 |
17 | // TOKEN
18 | //
19 | // This is the common interface for all token types. A token is a
20 | // block of information parsed from the input.
21 | public interface Token {
22 |
23 | // TO STRING
24 | //
25 | // Require all tokens to supply a |toString| implementation so that
26 | // tokens can be printed when debugging.
27 | String toString();
28 |
29 | // HASH CODE
30 | //
31 | // All tokens must implement hashCode to ensure that tokens can work
32 | // well with hash-based data structures.
33 | int hashCode();
34 |
35 | // EQUALS
36 | //
37 | // Check for equality with other objects. All tokens must implement
38 | // this to make working with tokens easier.
39 | boolean equals(Object other);
40 | }
41 |
--------------------------------------------------------------------------------
/src/com/google/codeu/mathlang/functions/operations/Operation.java:
--------------------------------------------------------------------------------
1 | // Copyright 2017 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.codeu.mathlang.functions.operations;
16 |
17 | public interface Operation {
18 |
19 | // APPLY TO
20 | //
21 | // Apply the operation to the value x and return the result.
22 | double applyTo(double x);
23 |
24 | // TO STRING
25 | //
26 | // All operations must supply a |toString| implementation so
27 | // operations can be printed when debugging.
28 | String toString();
29 |
30 | // HASH CODE
31 | //
32 | // All operations must implement hashCode to ensure that they can work
33 | // well with hash-based data structures.
34 | int hashCode();
35 |
36 | // EQUALS
37 | //
38 | // Check for euality with other objects. All operations must implement
39 | // this to make working with them easier.
40 | boolean equals(Object other);
41 | }
42 |
--------------------------------------------------------------------------------
/src/com/google/codeu/mathlang/parsing/TokenReader.java:
--------------------------------------------------------------------------------
1 | // Copyright 2017 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.codeu.mathlang.parsing;
16 |
17 | import java.io.IOException;
18 |
19 | import com.google.codeu.mathlang.core.tokens.Token;
20 |
21 | // TOKEN READER
22 | //
23 | // Defines a stream of tokens.
24 | public interface TokenReader {
25 |
26 | // NEXT
27 | //
28 | // Get the next token in the stream. When the end of stream has been reached
29 | // |next| should return |null|. The only valid tokens that can be returned are:
30 | // - com.google.codeu.mathlang.core.tokens.StringToken
31 | // - com.google.codeu.mathlang.core.tokens.NameToken
32 | // - com.google.codeu.mathlang.core.tokens.SymbolToken
33 | // - com.google.codeu.mathlang.core.tokens.NumberToken
34 | // If there is ever a problem with the source data, |next| should throw an
35 | // IOException.
36 | Token next() throws IOException;
37 | }
38 |
--------------------------------------------------------------------------------
/src/com/google/codeu/mathlang/core/tokens/NumberToken.java:
--------------------------------------------------------------------------------
1 | // Copyright 2017 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.codeu.mathlang.core.tokens;
16 |
17 | // NUMBER TOKEN
18 | //
19 | // This class represents a floating-point numerical token.
20 | public final class NumberToken implements Token {
21 |
22 | public final double value;
23 |
24 | public NumberToken(double value) {
25 | this.value = value;
26 | }
27 |
28 | @Override
29 | public String toString() {
30 | return String.format("NUMBER(%f)", value);
31 | }
32 |
33 | @Override
34 | public int hashCode() {
35 | return Double.hashCode(value);
36 | }
37 |
38 | @Override
39 | public boolean equals(Object other) {
40 | return other instanceof NumberToken && equals(this, (NumberToken) other);
41 | }
42 |
43 | private static boolean equals(NumberToken a, NumberToken b) {
44 | return a == b || (a != null && b != null && a.value == b.value);
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/com/google/codeu/mathlang/functions/operations/AddOperation.java:
--------------------------------------------------------------------------------
1 | // Copyright 2017 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.codeu.mathlang.functions.operations;
16 |
17 | public final class AddOperation implements Operation {
18 |
19 | private final double amount;
20 |
21 | public AddOperation(double amount) {
22 | this.amount = amount;
23 | }
24 |
25 | @Override
26 | public double applyTo(double x) {
27 | return x + amount;
28 | }
29 |
30 | @Override
31 | public String toString() { return String.format("ADD(%f)", amount); }
32 |
33 | @Override
34 | public int hashCode() { return Double.hashCode(amount); }
35 |
36 | @Override
37 | public boolean equals(Object other) {
38 | return other instanceof AddOperation && equals(this, (AddOperation) other);
39 | }
40 |
41 | private static final boolean equals(AddOperation a, AddOperation b) {
42 | return a == b || (a != null && b != null && a.amount == b.amount);
43 | }
44 | }
45 |
46 |
--------------------------------------------------------------------------------
/src/com/google/codeu/mathlang/core/tokens/NameToken.java:
--------------------------------------------------------------------------------
1 | // Copyright 2017 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.codeu.mathlang.core.tokens;
16 |
17 | // NAME TOKEN
18 | //
19 | // This class represents a UTF-8 string that contains no whitespaces
20 | // and starts with an alphabetical character.
21 | public final class NameToken implements Token {
22 |
23 | public final String value;
24 |
25 | public NameToken(String value) {
26 | this.value = value;
27 | }
28 |
29 | @Override
30 | public String toString() {
31 | return String.format("NAME(%s)", value);
32 | }
33 |
34 | @Override
35 | public int hashCode() {
36 | return value.hashCode();
37 | }
38 |
39 | @Override
40 | public boolean equals(Object other) {
41 | return other instanceof NameToken && equals(this, (NameToken) other);
42 | }
43 |
44 | private static boolean equals(NameToken a, NameToken b) {
45 | return a == b || (a != null && b!= null && a.value.equals(b.value));
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/com/google/codeu/mathlang/functions/operations/SubtractOperation.java:
--------------------------------------------------------------------------------
1 | // Copyright 2017 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.codeu.mathlang.functions.operations;
16 |
17 | public final class SubtractOperation implements Operation {
18 |
19 | private final double amount;
20 |
21 | public SubtractOperation(double amount) {
22 | this.amount = amount;
23 | }
24 |
25 | @Override
26 | public double applyTo(double x) {
27 | return x - amount;
28 | }
29 |
30 | @Override
31 | public String toString() { return String.format("SUB(%f)", amount); }
32 |
33 | @Override
34 | public int hashCode() { return Double.hashCode(amount); }
35 |
36 | @Override
37 | public boolean equals(Object other) {
38 | return other instanceof SubtractOperation && equals(this, (SubtractOperation) other);
39 | }
40 |
41 | private static final boolean equals(SubtractOperation a, SubtractOperation b) {
42 | return a == b || (a != null && b != null && a.amount == b.amount);
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/com/google/codeu/mathlang/core/tokens/StringToken.java:
--------------------------------------------------------------------------------
1 | // Copyright 2017 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.codeu.mathlang.core.tokens;
16 |
17 | // STRING TOKEN
18 | //
19 | // This class represents a UTF-8 string token. There are no restrictions
20 | // on what characters can be in it.
21 | public final class StringToken implements Token {
22 |
23 | public final String value;
24 |
25 | public StringToken(String value) {
26 | this.value = value;
27 | }
28 |
29 | @Override
30 | public String toString() {
31 | return String.format("STRING(%s)", value);
32 | }
33 |
34 | @Override
35 | public int hashCode() {
36 | return value.hashCode();
37 | }
38 |
39 | @Override
40 | public boolean equals(Object other) {
41 | return other instanceof StringToken && equals(this, (StringToken) other);
42 | }
43 |
44 | private static boolean equals(StringToken a, StringToken b) {
45 | return a == b || (a != null && b != null && a.value.equals(b.value));
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/com/google/codeu/mathlang/testing/TestNoteFunction.java:
--------------------------------------------------------------------------------
1 | // Copyright 2017 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.codeu.mathlang.testing;
16 |
17 | import java.util.Collection;
18 |
19 | import com.google.codeu.mathlang.functions.NoteFunction;
20 | import com.google.codeu.mathlang.testing.CallTable;
21 |
22 | // TEST NOTE FUNCTION
23 | //
24 | // Extend the Note Function and add entries to the call table
25 | // so that Note Function calls can be validated.
26 | public final class TestNoteFunction extends NoteFunction {
27 |
28 | private final CallTable table;
29 |
30 | public TestNoteFunction(CallTable table) {
31 | this.table = table;
32 | }
33 |
34 | @Override
35 | protected void onNoteBody(Collection segments) {
36 | // Add the call to the call table.
37 | final CallTable.Entry entry = table.newEntry();
38 | entry.and("note");
39 | for (final String segment : segments) {
40 | entry.and(segment);
41 | }
42 |
43 | super.onNoteBody(segments);
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/com/google/codeu/mathlang/core/tokens/SymbolToken.java:
--------------------------------------------------------------------------------
1 | // Copyright 2017 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.codeu.mathlang.core.tokens;
16 |
17 | // SYMBOL TOKEN
18 | //
19 | // This class represents a single character token. The internal value is
20 | // limited to characters that have a special meaning to the parser.
21 | public final class SymbolToken implements Token {
22 |
23 | public final char value;
24 |
25 | public SymbolToken(char value) {
26 | this.value = value;
27 | }
28 |
29 | @Override
30 | public String toString() {
31 | return String.format("SYMBOL(%c)", value);
32 | }
33 |
34 | @Override
35 | public int hashCode() {
36 | return Character.hashCode(value);
37 | }
38 |
39 | @Override
40 | public boolean equals(Object other) {
41 | return other instanceof SymbolToken && equals(this, (SymbolToken) other);
42 | }
43 |
44 | private static boolean equals(SymbolToken a, SymbolToken b) {
45 | return a == b || (a != null && b != null && a.value == b.value);
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/com/google/codeu/mathlang/parsing/StatementBuilder.java:
--------------------------------------------------------------------------------
1 | // Copyright 2017 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.codeu.mathlang.parsing;
16 |
17 | import java.util.ArrayList;
18 | import java.util.Collection;
19 |
20 | import com.google.codeu.mathlang.core.tokens.Token;
21 |
22 | // STATEMENT BUILDER
23 | //
24 | // The statement builder helps create a series of tokens. It supplies
25 | // an array of tokens when the series ends.
26 | final class StatementBuilder {
27 |
28 | private final Collection tokens = new ArrayList<>();
29 |
30 | // APPEND
31 | //
32 | // Add the token to the end of the series.
33 | public void append(Token token) {
34 | tokens.add(token);
35 | }
36 |
37 | // BUILD
38 | //
39 | // Create an array from the series of tokens.
40 | public Token[] build() {
41 | final Token[] out = new Token[tokens.size()];
42 | tokens.toArray(out);
43 | return out;
44 | }
45 |
46 | // RESET
47 | //
48 | // Reset the internal state of the builder. This should be called
49 | // before starting to append the tokens of a statement.
50 | public void reset() {
51 | tokens.clear();
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/com/google/codeu/mathlang/testing/TestPrintFunction.java:
--------------------------------------------------------------------------------
1 | // Copyright 2017 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.codeu.mathlang.testing;
16 |
17 | import java.util.Collection;
18 | import java.util.Map;
19 |
20 | import com.google.codeu.mathlang.core.Variable;
21 | import com.google.codeu.mathlang.functions.PrintFunction;
22 | import com.google.codeu.mathlang.testing.CallTable;
23 |
24 | // TEST PRINT FUNCTION
25 | //
26 | // Extend the Print Function and add entries to the call table
27 | // so that Print Function calls can be validated.
28 | public final class TestPrintFunction extends PrintFunction {
29 |
30 | private final CallTable table;
31 |
32 | public TestPrintFunction(Map variables, CallTable table) {
33 | super(variables);
34 | this.table = table;
35 | }
36 |
37 | @Override
38 | protected void printLine(Collection segments) {
39 | // Add the call to the call table.
40 | final CallTable.Entry entry = table.newEntry();
41 | entry.and("print");
42 | for (final String segment : segments) {
43 | entry.and(segment);
44 | }
45 |
46 | super.printLine(segments);
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/com/google/codeu/mathlang/testing/TestLetFunction.java:
--------------------------------------------------------------------------------
1 | // Copyright 2017 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.codeu.mathlang.testing;
16 |
17 | import java.util.Collection;
18 | import java.util.Map;
19 |
20 | import com.google.codeu.mathlang.core.Variable;
21 | import com.google.codeu.mathlang.functions.LetFunction;
22 | import com.google.codeu.mathlang.functions.operations.Operation;
23 | import com.google.codeu.mathlang.testing.CallTable;
24 |
25 | // TEST LET FUNCTION
26 | //
27 | // Extend the Let Function and add entries to the call table
28 | // so Let Function calls can be validated.
29 | public final class TestLetFunction extends LetFunction {
30 |
31 | private final CallTable table;
32 |
33 | public TestLetFunction(Map variables, CallTable table) {
34 | super(variables);
35 | this.table = table;
36 | }
37 |
38 | @Override
39 | protected double evaluate(Collection ops) {
40 | // Add the call to the call table.
41 | final CallTable.Entry entry = table.newEntry();
42 | entry.and("let");
43 | for (final Operation op : ops) {
44 | entry.and(op);
45 | }
46 |
47 | return super.evaluate(ops);
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/com/google/codeu/mathlang/impl/MyTokenReader.java:
--------------------------------------------------------------------------------
1 | // Copyright 2017 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.codeu.mathlang.impl;
16 |
17 | import java.io.IOException;
18 |
19 | import com.google.codeu.mathlang.core.tokens.Token;
20 | import com.google.codeu.mathlang.parsing.TokenReader;
21 |
22 | // MY TOKEN READER
23 | //
24 | // This is YOUR implementation of the token reader interface. To know how
25 | // it should work, read src/com/google/codeu/mathlang/parsing/TokenReader.java.
26 | // You should not need to change any other files to get your token reader to
27 | // work with the test of the system.
28 | public final class MyTokenReader implements TokenReader {
29 |
30 | public MyTokenReader(String source) {
31 | // Your token reader will only be given a string for input. The string will
32 | // contain the whole source (0 or more lines).
33 | }
34 |
35 | @Override
36 | public Token next() throws IOException {
37 | // Most of your work will take place here. For every call to |next| you should
38 | // return a token until you reach the end. When there are no more tokens, you
39 | // should return |null| to signal the end of input.
40 |
41 | // If for any reason you detect an error in the input, you may throw an IOException
42 | // which will stop all execution.
43 |
44 | return null;
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # CodeU Coding Assessment - Math Lang
2 |
3 | # Overview
4 | This project allows students to demonstrate their coding skills by implementing
5 | a component of a larger system.
6 |
7 | MathLang is a made-up math scripting language. Students are expected to
8 | implement `com.google.codeu.mathlang.impl.MyTokenReader`. The class has already
9 | been created and students only need to finish implementing its functionality.
10 |
11 | `MyTokenReader` is responsible for parsing the text input and converting it to
12 | a stream of tokens that the MathLang parser will use to build statements.
13 | Statements are then passed to the interpreter to be executed. Everything except
14 | for `MyTokenReader` has already been implemented.
15 |
16 | To further understand how `MyTokenReader` should behave, students can look at
17 | `com.google.codeu.mathlang.core.tokens.TokenReader`. `TokenReader` is the
18 | interface that `MyTokenReader` implements and contains in-code documentation
19 | for how each method should behave.
20 |
21 | # The Goal
22 | When students have finished their implementation of `MyTokenReader`, they should
23 | run the tests and see all tests pass. If any test fails, the student is not
24 | done. The tests provided are only for testing MathLang. There are no tests for
25 | `MyTokenReader`. Students are encouraged to write their own tests to ensure
26 | their implementation is working.
27 |
28 | Students should not use any third-party libraries to complete this assessment.
29 | The one exception is the use of a third-party test library to help test their
30 | implementation of `MyTokenReader`.
31 |
32 | When done, an evaluator should be able to run the student's project using the
33 | same build and run instructions provided here. This means that if a student
34 | uses a third-party test library, all dependencies must be included with the
35 | project and `build.sh` and `run.sh` must be updated.
36 |
37 | # Build Instructions
38 | These instructions are based on a Linux environment using BASH and JAVA 7.
39 |
40 | To clean, run `./clean.sh`.
41 | To build, run `./build.sh`.
42 | To run all tests, run `./run.sh`.
--------------------------------------------------------------------------------
/src/com/google/codeu/mathlang/core/State.java:
--------------------------------------------------------------------------------
1 | // Copyright 2017 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.codeu.mathlang.core;
16 |
17 | import java.util.HashMap;
18 | import java.util.Map;
19 |
20 | import com.google.codeu.mathlang.core.tokens.NameToken;
21 | import com.google.codeu.mathlang.core.tokens.Token;
22 |
23 | // STATE
24 | //
25 | // This class represents the execution environment for all functions. State
26 | // maintains a list of all functions and routes statements to the correct
27 | // function.
28 | public final class State {
29 |
30 | private final Map functions = new HashMap<>();
31 |
32 | // DEFINE FUNCTION
33 | //
34 | // Assign a function to a keyword. This will overwrite any previous assigned
35 | // function with the same name.
36 | public void defineFunction(String name, Function function) {
37 | functions.put(name, function);
38 | }
39 |
40 | // RUN
41 | //
42 | // Find the correct function for the given statement and execute the
43 | // statement.
44 | public void run(Token[] statement) throws Exception {
45 |
46 | if (statement.length == 0) {
47 | // An empty statement should act like a No-op.
48 | return;
49 | }
50 |
51 | final Token head = statement[0];
52 |
53 | if (!(head instanceof NameToken)) {
54 | throw new Exception(String.format("Expecting name token but found %s", head));
55 | }
56 |
57 | final NameToken name = (NameToken) head;
58 | final Function function = functions.get(name.value);
59 |
60 | if (function == null) {
61 | throw new Exception(String.format("Unknown function \"%s\"", name.value));
62 | }
63 |
64 | function.run(statement);
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/com/google/codeu/mathlang/functions/NoteFunction.java:
--------------------------------------------------------------------------------
1 | // Copyright 2017 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.codeu.mathlang.functions;
16 |
17 | import java.util.ArrayList;
18 | import java.util.Collection;
19 |
20 | import com.google.codeu.mathlang.core.Function;
21 | import com.google.codeu.mathlang.core.tokens.StringToken;
22 | import com.google.codeu.mathlang.core.tokens.Token;
23 |
24 | // NOTE FUNCTION
25 | //
26 | // This class defines the note functionality of mathlang. A note is similar
27 | // to a comment in other programming languages. However, in Mathlang the only
28 | // text that can appear in a note are quoted strings. For example:
29 | // NOTE "this is a note";
30 | // NOTE "this is the first half" "and this is this second";
31 | // Note "this is the first half"
32 | // "and this is the second";
33 | //
34 | // This class is not marked as final so that it can be overriden in our tests.
35 | public class NoteFunction implements Function {
36 |
37 | @Override
38 | public void run(Token[] statement) throws Exception {
39 |
40 | final Collection segments = new ArrayList<>();
41 |
42 | for (int i = 1; i < statement.length; i++) {
43 | if (statement[i] instanceof StringToken) {
44 | final StringToken string = (StringToken) statement[i];
45 | segments.add(string.value);
46 | } else {
47 | throw new Exception(String.format("NOTE should only contain string values but found %s", statement[i]));
48 | }
49 | }
50 |
51 | onNoteBody(segments);
52 | }
53 |
54 | // ON NOTE BODY
55 | //
56 | // This method does not need to do anything. It is exposed so NOTE
57 | // calls can be checked in our tests.
58 | protected void onNoteBody(Collection segments) { }
59 | }
60 |
--------------------------------------------------------------------------------
/src/com/google/codeu/mathlang/parsing/StatementReader.java:
--------------------------------------------------------------------------------
1 | // Copyright 2017 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.codeu.mathlang.parsing;
16 |
17 | import java.io.IOException;
18 |
19 | import com.google.codeu.mathlang.core.tokens.Token;
20 | import com.google.codeu.mathlang.core.tokens.SymbolToken;
21 |
22 | // STATEMENT READER
23 | //
24 | // The statement reader takes a token reader and creates a stream
25 | // of executable statements.
26 | public final class StatementReader {
27 |
28 | private static final Token END_OF_STATEMENT = new SymbolToken(';');
29 |
30 | private final StatementBuilder builder = new StatementBuilder();
31 | private final TokenReader reader;
32 |
33 | public StatementReader(TokenReader reader) {
34 | this.reader = reader;
35 | }
36 |
37 | // NEXT
38 | //
39 | // Get the next statement as an array of tokens. When the end of stream is
40 | // reached (there are no more statements) this method returns null. This
41 | // method will only return complete statements, if an end of stream is reached
42 | // before a complete statement is recognized, an IOException will be thrown.
43 | public Token[] next() throws IOException {
44 | builder.reset();
45 |
46 | Token next = reader.next();
47 |
48 | // If there is nothing when we start reading, assume that we made it to the
49 | // end of the stream safely.
50 | if (next == null) {
51 | return null;
52 | }
53 |
54 | while (next != null && !next.equals(END_OF_STATEMENT)) {
55 | builder.append(next);
56 | next = reader.next();
57 | }
58 |
59 | // If next is null here it means that the last statement is incomplete.
60 | if (next == null) {
61 | throw new IOException("Reached end of stream while still reading statement.");
62 | }
63 |
64 | return builder.build();
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/com/google/codeu/mathlang/testing/CallTable.java:
--------------------------------------------------------------------------------
1 | // Copyright 2017 Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package com.google.codeu.mathlang.testing;
16 |
17 | import java.util.ArrayList;
18 | import java.util.Arrays;
19 | import java.util.Collection;
20 | import java.util.LinkedList;
21 | import java.util.List;
22 | import java.util.Queue;
23 |
24 | // CALL TABLE
25 | //
26 | // This class is used to verify that specific methods within a target class
27 | // have been called with the expected arguments in a specific order. For a given
28 | // target class, a subclass must be defined that overrides each method of the
29 | // target class with a method that writes to the call table. The call table
30 | // can then be checked to see if the expected calls were made.
31 | public final class CallTable {
32 |
33 | public interface Entry {
34 | Entry and(Object value);
35 | };
36 |
37 | private final Queue> entries = new LinkedList<>();
38 |
39 | // NEW ENTRY
40 | //
41 | // Create a new entry in the call table. This method returns an |Entry| which
42 | // holds information about the call.
43 | public Entry newEntry() {
44 | final List