├── .github
├── ISSUE_TEMPLATE
│ ├── bug-report.yml
│ ├── config.yml
│ └── feature-request.yml
└── workflows
│ ├── build-release.yml
│ ├── ci.yml
│ └── unsigned_release.yml
├── .gitignore
├── .idea
├── .gitignore
├── AndroidProjectSystem.xml
├── compiler.xml
├── deploymentTargetDropDown.xml
├── deploymentTargetSelector.xml
├── gradle.xml
├── inspectionProfiles
│ └── Project_Default.xml
├── kotlinc.xml
├── ktlint.xml
├── migrations.xml
├── misc.xml
├── runConfigurations.xml
└── vcs.xml
├── LICENSE
├── README.md
├── app
├── .gitignore
├── build.gradle.kts
├── proguard-rules.pro
├── release
│ └── output-metadata.json
└── src
│ ├── androidTest
│ └── java
│ │ └── net
│ │ └── youapps
│ │ └── calcyou
│ │ └── ExampleInstrumentedTest.kt
│ ├── debug
│ └── res
│ │ └── values
│ │ └── strings.xml
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── net
│ │ │ └── youapps
│ │ │ └── calcyou
│ │ │ ├── CalculatorApplication.kt
│ │ │ ├── Destination.kt
│ │ │ ├── MainActivity.kt
│ │ │ ├── NavHost.kt
│ │ │ ├── data
│ │ │ ├── CalculatorEvent.kt
│ │ │ ├── Evaluator.kt
│ │ │ ├── EventHandler.kt
│ │ │ ├── InsertText.kt
│ │ │ ├── KeyMap.kt
│ │ │ ├── Operators.kt
│ │ │ ├── Tokenizer.kt
│ │ │ ├── converters
│ │ │ │ ├── AngleConverter.kt
│ │ │ │ ├── AreaConverter.kt
│ │ │ │ ├── ConverterUnit.kt
│ │ │ │ ├── DensityConverter.kt
│ │ │ │ ├── DigitalStorageConverter.kt
│ │ │ │ ├── EnergyConverter.kt
│ │ │ │ ├── FactorUnit.kt
│ │ │ │ ├── ForceConverter.kt
│ │ │ │ ├── FrequencyConverter.kt
│ │ │ │ ├── FuelConverter.kt
│ │ │ │ ├── LengthConverter.kt
│ │ │ │ ├── LightConverter.kt
│ │ │ │ ├── MassConverter.kt
│ │ │ │ ├── PowerConverter.kt
│ │ │ │ ├── PressureConverter.kt
│ │ │ │ ├── SpeedConverter.kt
│ │ │ │ ├── TemperatureConverter.kt
│ │ │ │ ├── TimeConverter.kt
│ │ │ │ ├── TorqueConverter.kt
│ │ │ │ ├── UnitConverter.kt
│ │ │ │ ├── ViscosityConverter.kt
│ │ │ │ └── VolumeConverter.kt
│ │ │ └── graphing
│ │ │ │ ├── CompiledExpression.kt
│ │ │ │ ├── Constant.kt
│ │ │ │ ├── Defaults.kt
│ │ │ │ ├── EvalConfig.kt
│ │ │ │ ├── Evaluator.kt
│ │ │ │ ├── Function.kt
│ │ │ │ ├── OffsetConverters.kt
│ │ │ │ ├── Token.kt
│ │ │ │ └── Window.kt
│ │ │ ├── ui
│ │ │ ├── CalculatorScreen.kt
│ │ │ ├── MainScreen.kt
│ │ │ ├── components
│ │ │ │ ├── AddNewConstantDialog.kt
│ │ │ │ ├── AddNewFunctionDialog.kt
│ │ │ │ ├── CalculatorDisplay.kt
│ │ │ │ ├── ColorSelectionDialog.kt
│ │ │ │ ├── ConverterCard.kt
│ │ │ │ ├── Keypad.kt
│ │ │ │ ├── NavDrawerContent.kt
│ │ │ │ ├── SwipePanels.kt
│ │ │ │ └── buttons
│ │ │ │ │ ├── CalculatorButton.kt
│ │ │ │ │ ├── CalculatorTextButton.kt
│ │ │ │ │ ├── KeyRow.kt
│ │ │ │ │ ├── KeyboardKey.kt
│ │ │ │ │ └── KeyboardPanel.kt
│ │ │ ├── screens
│ │ │ │ ├── CharacterInputScreen.kt
│ │ │ │ ├── ConverterGridScreen.kt
│ │ │ │ ├── ConverterScreen.kt
│ │ │ │ └── graphing
│ │ │ │ │ ├── CanvasView.kt
│ │ │ │ │ ├── GraphingScreen.kt
│ │ │ │ │ └── GraphingUtils.kt
│ │ │ └── theme
│ │ │ │ ├── Color.kt
│ │ │ │ ├── Theme.kt
│ │ │ │ └── Type.kt
│ │ │ └── viewmodels
│ │ │ ├── CalculatorViewModel.kt
│ │ │ └── GraphViewModel.kt
│ └── res
│ │ ├── drawable
│ │ ├── bracket_l.xml
│ │ ├── bracket_r.xml
│ │ ├── delete.xml
│ │ ├── divide.xml
│ │ ├── equal.xml
│ │ ├── ic_launcher_foreground.xml
│ │ ├── ic_launcher_monochrome.xml
│ │ ├── minus.xml
│ │ ├── multiply.xml
│ │ ├── percent.xml
│ │ └── plus.xml
│ │ ├── mipmap-anydpi-v26
│ │ └── ic_launcher.xml
│ │ ├── mipmap-hdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-mdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-xhdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-xxhdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-xxxhdpi
│ │ └── ic_launcher.png
│ │ ├── values-ar
│ │ └── strings.xml
│ │ ├── values-az
│ │ └── strings.xml
│ │ ├── values-ca
│ │ └── strings.xml
│ │ ├── values-cs
│ │ └── strings.xml
│ │ ├── values-de
│ │ └── strings.xml
│ │ ├── values-el
│ │ └── strings.xml
│ │ ├── values-es
│ │ └── strings.xml
│ │ ├── values-et
│ │ └── strings.xml
│ │ ├── values-fa
│ │ └── strings.xml
│ │ ├── values-fi
│ │ └── strings.xml
│ │ ├── values-fil
│ │ └── strings.xml
│ │ ├── values-fr
│ │ └── strings.xml
│ │ ├── values-hi
│ │ └── strings.xml
│ │ ├── values-ia
│ │ └── strings.xml
│ │ ├── values-in
│ │ └── strings.xml
│ │ ├── values-it
│ │ └── strings.xml
│ │ ├── values-iw
│ │ └── strings.xml
│ │ ├── values-lt
│ │ └── strings.xml
│ │ ├── values-nb-rNO
│ │ └── strings.xml
│ │ ├── values-night
│ │ └── colors.xml
│ │ ├── values-pl
│ │ └── strings.xml
│ │ ├── values-pt-rBR
│ │ └── strings.xml
│ │ ├── values-pt
│ │ └── strings.xml
│ │ ├── values-ru
│ │ └── strings.xml
│ │ ├── values-sv
│ │ └── strings.xml
│ │ ├── values-ta
│ │ └── strings.xml
│ │ ├── values-tr
│ │ └── strings.xml
│ │ ├── values-uk
│ │ └── strings.xml
│ │ ├── values-vi
│ │ └── strings.xml
│ │ ├── values-zh-rCN
│ │ └── strings.xml
│ │ ├── values-zh-rTW
│ │ └── strings.xml
│ │ ├── values
│ │ ├── colors.xml
│ │ ├── ic_launcher_background.xml
│ │ ├── strings.xml
│ │ └── themes.xml
│ │ └── xml
│ │ ├── backup_rules.xml
│ │ └── data_extraction_rules.xml
│ └── test
│ └── java
│ └── net
│ └── youapps
│ └── calcyou
│ ├── EvaluatorTest.kt
│ └── ExampleUnitTest.kt
├── arity
├── .gitignore
├── build.gradle.kts
└── src
│ └── main
│ └── java
│ └── org
│ └── javia
│ └── arity
│ ├── ArityException.java
│ ├── ByteStack.java
│ ├── CompiledFunction.java
│ ├── CompiledFunction.java.orig
│ ├── Compiler.java
│ ├── Compiler.java.orig
│ ├── Complex.java
│ ├── Constant.java
│ ├── ContextFunction.java
│ ├── Declaration.java
│ ├── DeclarationParser.java
│ ├── Derivative.java
│ ├── DoubleStack.java
│ ├── EvalContext.java
│ ├── Function.java
│ ├── FunctionAndName.java
│ ├── FunctionStack.java
│ ├── IsComplexException.java
│ ├── Lexer.java
│ ├── Lexer.java.orig
│ ├── MoreMath.java
│ ├── OptCodeGen.java
│ ├── RPN.java
│ ├── SimpleCodeGen.java
│ ├── Symbol.java
│ ├── Symbols.java
│ ├── SyntaxException.java
│ ├── Token.java
│ ├── TokenConsumer.java
│ ├── UnitTest.java
│ ├── Util.java
│ └── VM.java
├── build.gradle.kts
├── fastlane
└── metadata
│ └── android
│ └── en-US
│ ├── full_description.txt
│ ├── images
│ ├── icon.png
│ └── phoneScreenshots
│ │ ├── 1.png
│ │ ├── 2.png
│ │ ├── 3.png
│ │ ├── 4.png
│ │ └── 5.png
│ └── short_description.txt
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle.kts
/.github/ISSUE_TEMPLATE/bug-report.yml:
--------------------------------------------------------------------------------
1 | name: 🐞 Bug Report
2 | description: Report an issue in the app
3 | labels: [bug]
4 | body:
5 |
6 | - type: textarea
7 | id: reproduce-steps
8 | attributes:
9 | label: Steps to reproduce
10 | description: Provide an example of the issue.
11 | placeholder: |
12 | Example:
13 | 1. First step
14 | 2. Second step
15 | 3. Issue here
16 | validations:
17 | required: true
18 |
19 | - type: textarea
20 | id: expected-behavior
21 | attributes:
22 | label: Expected behavior
23 | placeholder: |
24 | Example:
25 | "This should happen..."
26 | validations:
27 | required: true
28 |
29 | - type: textarea
30 | id: actual-behavior
31 | attributes:
32 | label: Actual behavior
33 | placeholder: |
34 | Example:
35 | "This happened instead..."
36 | validations:
37 | required: true
38 |
39 | - type: input
40 | id: Calc_You-version
41 | attributes:
42 | label: Calc You version
43 | description: |
44 | You can find your Calc You version in **About**.
45 | placeholder: |
46 | Example: "0.5.0"
47 | validations:
48 | required: true
49 |
50 | - type: input
51 | id: android-version
52 | attributes:
53 | label: Android version
54 | description: |
55 | You can find this somewhere in your Android settings.
56 | placeholder: |
57 | Example: "Android 12"
58 | validations:
59 | required: true
60 |
61 | - type: textarea
62 | id: other-details
63 | attributes:
64 | label: Other details
65 | placeholder: |
66 | Additional details and attachments.
67 |
68 | - type: checkboxes
69 | id: acknowledgements
70 | attributes:
71 | label: Acknowledgements
72 | description: Your issue will be closed if you haven't done these steps.
73 | options:
74 | - label: I have searched the existing issues and this is a new ticket, **NOT** a duplicate or related to another open issue.
75 | required: true
76 | - label: I have written a short but informative title.
77 | required: true
78 | - label: I will fill out all of the requested information in this form.
79 | required: true
80 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/config.yml:
--------------------------------------------------------------------------------
1 | blank_issues_enabled: false
2 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature-request.yml:
--------------------------------------------------------------------------------
1 | name: ⭐ Feature request
2 | description: Suggest a feature to improve Calc You
3 | labels: [enhancement]
4 | body:
5 |
6 | - type: textarea
7 | id: feature-description
8 | attributes:
9 | label: Describe your suggested feature
10 | description: How can an existing source be improved?
11 | placeholder: |
12 | Example:
13 | "It could work like this..."
14 | validations:
15 | required: true
16 |
17 | - type: textarea
18 | id: other-details
19 | attributes:
20 | label: Other details
21 | placeholder: |
22 | Additional details and attachments.
23 |
24 | - type: checkboxes
25 | id: acknowledgements
26 | attributes:
27 | label: Acknowledgements
28 | description: Your issue will be closed if you haven't done these steps.
29 | options:
30 | - label: I have searched the existing issues and this is a new ticket, **NOT** a duplicate or related to another open issue.
31 | required: true
32 | - label: I'm not requesting to add a new unit converter or to modify an existing one.
33 | required: true
34 | - label: I have written a short but informative title.
35 | required: true
36 | - label: I will fill out all of the requested information in this form.
37 | required: true
38 |
--------------------------------------------------------------------------------
/.github/workflows/build-release.yml:
--------------------------------------------------------------------------------
1 | name: Build and release app
2 |
3 | on:
4 | workflow_dispatch:
5 | push:
6 | tags:
7 | - 'v*.*'
8 |
9 | jobs:
10 | build:
11 | name: Build, sign and release app
12 | runs-on: ubuntu-latest
13 | permissions:
14 | contents: write
15 | steps:
16 | - uses: actions/checkout@v4
17 |
18 | - name: Set up JDK
19 | uses: actions/setup-java@v4
20 | with:
21 | distribution: "zulu"
22 | java-version: "17"
23 | cache: "gradle"
24 |
25 | - name: Build APK
26 | run: ./gradlew assembleRelease --no-daemon
27 |
28 | - name: Sign APK
29 | uses: ilharp/sign-android-release@v1
30 | id: sign
31 | with:
32 | signingKey: ${{ secrets.KEYSTORE }}
33 | keyAlias: ${{ secrets.SIGNING_KEY_ALIAS }}
34 | keyStorePassword: ${{ secrets.SIGNING_STORE_PASSWORD }}
35 | keyPassword: ${{ secrets.SIGNING_KEY_PASSWORD }}
36 | buildToolsVersion: 35.0.0
37 |
38 | - name: Rename signed APK
39 | run: |
40 | mv "${{ steps.sign.outputs.signedFile }}" "app-release.apk"
41 |
42 | - name: Create changelog
43 | id: changelog
44 | uses: requarks/changelog-action@v1
45 | with:
46 | token: ${{ github.token }}
47 | tag: ${{ github.ref_name }}
48 |
49 | - name: Create release
50 | uses: softprops/action-gh-release@v2
51 | with:
52 | body: ${{ steps.changelog.outputs.changes }}
53 | files: "app-release.apk"
54 | fail_on_unmatched_files: true
55 | make_latest: true
56 |
--------------------------------------------------------------------------------
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | name: Create Debug Apk
2 |
3 | on:
4 | push:
5 | paths-ignore:
6 | - "README*.md"
7 | - "app/src/main/res/**"
8 | - ".github/**"
9 | pull_request:
10 | paths-ignore:
11 | - "README*.md"
12 | - "app/src/main/res/**"
13 | - ".github/**"
14 |
15 | jobs:
16 | debug-builds:
17 | runs-on: ubuntu-latest
18 | steps:
19 | - name: Checkout
20 | uses: actions/checkout@v4
21 |
22 | - name: Validate Gradle Wrapper
23 | uses: gradle/wrapper-validation-action@v2
24 |
25 | - name: Setup JDK
26 | uses: actions/setup-java@v4
27 | with:
28 | java-version: 17
29 | distribution: "temurin"
30 | cache: "gradle"
31 |
32 | - name: Build APK
33 | run: bash ./gradlew assembleDebug --stacktrace
34 |
35 | - name: Upload APK
36 | uses: actions/upload-artifact@v4
37 | with:
38 | name: app
39 | path: app/build/outputs/apk/debug/*.apk
40 |
--------------------------------------------------------------------------------
/.github/workflows/unsigned_release.yml:
--------------------------------------------------------------------------------
1 | name: Create Unsigned Release APK
2 |
3 | on:
4 | workflow_dispatch:
5 |
6 | jobs:
7 | debug-builds:
8 | runs-on: ubuntu-latest
9 | steps:
10 | - name: Checkout
11 | uses: actions/checkout@v4
12 |
13 | - name: Validate Gradle Wrapper
14 | uses: gradle/wrapper-validation-action@v2
15 |
16 | - name: Setup JDK
17 | uses: actions/setup-java@v4
18 | with:
19 | java-version: 17
20 | distribution: "temurin"
21 |
22 | - name: Build APK
23 | run: bash ./gradlew assembleRelease --stacktrace
24 |
25 | - name: Upload APK
26 | uses: actions/upload-artifact@v4
27 | with:
28 | name: app
29 | path: app/build/outputs/apk/release/*.apk
30 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/caches
5 | /.idea/libraries
6 | /.idea/modules.xml
7 | /.idea/workspace.xml
8 | /.idea/navEditor.xml
9 | /.idea/assetWizardSettings.xml
10 | .DS_Store
11 | /build
12 | /captures
13 | .externalNativeBuild
14 | .cxx
15 | local.properties
16 |
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 |
--------------------------------------------------------------------------------
/.idea/AndroidProjectSystem.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
11 |
Privacy focused calculator app built with MD3.
6 | 7 | 8 |
25 |
26 |
27 |
28 |
30 |
31 |
32 |
21 | */ 22 | class Compiler { 23 | private final SyntaxException exception = new SyntaxException(); 24 | private final Lexer lexer = new Lexer(exception); 25 | private final RPN rpn = new RPN(exception); 26 | private final DeclarationParser declParser = new DeclarationParser(exception); 27 | private final OptCodeGen codeGen = new OptCodeGen(exception); 28 | private final SimpleCodeGen simpleCodeGen = new SimpleCodeGen(exception); 29 | private final Declaration decl = new Declaration(); 30 | 31 | Function compileSimple(Symbols symbols, String expression) throws SyntaxException { 32 | rpn.setConsumer(simpleCodeGen.setSymbols(symbols)); 33 | lexer.scan(expression, rpn); 34 | return simpleCodeGen.getFun(); 35 | } 36 | 37 | Function compile(Symbols symbols, String source) throws SyntaxException { 38 | Function fun = null; 39 | decl.parse(source, lexer, declParser); 40 | if (decl.arity == DeclarationParser.UNKNOWN_ARITY) { 41 | try { 42 | fun = new Constant(compileSimple(symbols, decl.expression).evalComplex()); 43 | } catch (SyntaxException e) { 44 | if (e != SimpleCodeGen.HAS_ARGUMENTS) { 45 | throw e; 46 | } 47 | // fall-through (see below) 48 | } 49 | } 50 | 51 | if (fun == null) { 52 | // either decl.arity was set, or an HAS_ARGUMENTS exception ocurred above 53 | symbols.pushFrame(); 54 | symbols.addArguments(decl.args); 55 | try { 56 | rpn.setConsumer(codeGen.setSymbols(symbols)); 57 | lexer.scan(decl.expression, rpn); 58 | } finally { 59 | symbols.popFrame(); 60 | } 61 | int arity = decl.arity; 62 | if (arity == DeclarationParser.UNKNOWN_ARITY) { 63 | arity = codeGen.intrinsicArity; 64 | } 65 | fun = codeGen.getFun(arity); 66 | } 67 | fun.comment = source; 68 | return fun; 69 | } 70 | 71 | FunctionAndName compileWithName(Symbols symbols, String source) throws SyntaxException { 72 | return new FunctionAndName(compile(symbols, source), decl.name); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /arity/src/main/java/org/javia/arity/Compiler.java.orig: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007-2009 Mihai Preda. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.javia.arity; 18 | 19 | /** 20 | Compiles a textual arithmetic expression to a {@link Function}.
21 | */
22 | class Compiler {
23 | private final SyntaxException exception = new SyntaxException();
24 | private final Lexer lexer = new Lexer(exception);
25 | private final RPN rpn = new RPN(exception);
26 | private final DeclarationParser declParser = new DeclarationParser(exception);
27 | private final OptCodeGen codeGen = new OptCodeGen(exception);
28 | private final SimpleCodeGen simpleCodeGen = new SimpleCodeGen(exception);
29 | private final Declaration decl = new Declaration();
30 |
31 | Function compileSimple(Symbols symbols, String expression) throws SyntaxException {
32 | rpn.setConsumer(simpleCodeGen.setSymbols(symbols));
33 | lexer.scan(expression, rpn);
34 | return simpleCodeGen.getFun();
35 | }
36 |
37 | Function compile(Symbols symbols, String source) throws SyntaxException {
38 | Function fun = null;
39 | decl.parse(source, lexer, declParser);
40 | if (decl.arity == DeclarationParser.UNKNOWN_ARITY) {
41 | try {
42 | fun = new Constant(compileSimple(symbols, decl.expression).evalComplex());
43 | } catch (SyntaxException e) {
44 | if (e != SimpleCodeGen.HAS_ARGUMENTS) {
45 | throw e;
46 | }
47 | // fall-through (see below)
48 | }
49 | }
50 |
51 | if (fun == null) {
52 | // either decl.arity was set, or an HAS_ARGUMENTS exception ocurred above
53 | symbols.pushFrame();
54 | symbols.addArguments(decl.args);
55 | try {
56 | rpn.setConsumer(codeGen.setSymbols(symbols));
57 | lexer.scan(decl.expression, rpn);
58 | } finally {
59 | symbols.popFrame();
60 | }
61 | int arity = decl.arity;
62 | if (arity == DeclarationParser.UNKNOWN_ARITY) {
63 | arity = codeGen.intrinsicArity;
64 | }
65 | fun = codeGen.getFun(arity);
66 | }
67 | fun.comment = source;
68 | return fun;
69 | }
70 |
71 | FunctionAndName compileWithName(Symbols symbols, String source) throws SyntaxException {
72 | return new FunctionAndName(compile(symbols, source), decl.name);
73 | }
74 |
75 | private static final Function EMPTY_FUNCS = {};
76 | Function[] compileMultiple(Symbols symbols, String source) {
77 | codeGen.setSymbols(symbols);
78 | rpn.setConsumer(codeGen);
79 | int len = symbols.length();
80 | ArrayList
21 | * A function has an arity (the number of arguments), and a way for evaluation
22 | * given the values of the arguments.
23 | * To create user-defined functions,
24 | * derive from this class and override one of the eval() methods.
25 | *
26 | * If the user subclasses Function, he is responsible for the thread-safety of
27 | * his user-defined Functions.
28 | */
29 |
30 | abstract public class Function {
31 | String comment;
32 | private Function cachedDerivate = null;
33 |
34 | /**
35 | * Gives the arity of this function.
36 | *
37 | * @return the arity (the number of arguments). Arity >= 0.
38 | */
39 | abstract public int arity();
40 |
41 | public Function getDerivative() {
42 | if (cachedDerivate == null) {
43 | cachedDerivate = new Derivative(this);
44 | }
45 | return cachedDerivate;
46 | }
47 |
48 | void setDerivative(Function deriv) {
49 | cachedDerivate = deriv;
50 | }
51 |
52 | /**
53 | * Evaluates an arity-0 function (a function with no arguments).
54 | *
55 | * @return the value of the function
56 | */
57 | public double eval() {
58 | throw new ArityException(0);
59 | }
60 |
61 | /**
62 | * Evaluates a function with a single argument (arity == 1).
63 | */
64 | public double eval(double x) {
65 | throw new ArityException(1);
66 | }
67 |
68 | /**
69 | * Evaluates a function with two arguments (arity == 2).
70 | */
71 | public double eval(double x, double y) {
72 | throw new ArityException(2);
73 | }
74 |
75 | /**
76 | * Evaluates the function given the argument values.
77 | *
78 | * @param args array containing the arguments.
79 | * @return the value of the function
80 | * @throws ArityException if args.length != arity.
81 | */
82 | public double eval(double args[]) {
83 | switch (args.length) {
84 | case 0:
85 | return eval();
86 | case 1:
87 | return eval(args[0]);
88 | case 2:
89 | return eval(args[0], args[1]);
90 | }
91 | throw new ArityException(args.length);
92 | }
93 |
94 |
95 | /**
96 | * By default complex forwards to real eval is the arguments are real,
97 | * otherwise returns NaN.
98 | * This allow calling any real functions as a (restricted) complex one.
99 | */
100 | public Complex evalComplex() {
101 | checkArity(0);
102 | return new Complex(eval(), 0);
103 | }
104 |
105 | /**
106 | * Complex evaluates a function with a single argument.
107 | */
108 | public Complex eval(Complex x) {
109 | checkArity(1);
110 | return new Complex(x.im == 0 ? eval(x.re) : Double.NaN, 0);
111 | }
112 |
113 | /**
114 | * Complex evaluates a function with two arguments.
115 | */
116 | public Complex eval(Complex x, Complex y) {
117 | checkArity(2);
118 | return new Complex(x.im == 0 && y.im == 0 ? eval(x.re, y.re) : Double.NaN, 0);
119 | }
120 |
121 | /**
122 | * Complex evaluates a function with an arbitrary number of arguments.
123 | */
124 | public Complex eval(Complex args[]) {
125 | switch (args.length) {
126 | case 0:
127 | return evalComplex();
128 | case 1:
129 | return eval(args[0]);
130 | case 2:
131 | return eval(args[0], args[1]);
132 | default:
133 | int len = args.length;
134 | checkArity(len);
135 | double reArgs[] = new double[len];
136 | for (int i = args.length - 1; i >= 0; --i) {
137 | if (args[i].im != 0) {
138 | return new Complex(Double.NaN, 0);
139 | }
140 | reArgs[i] = args[i].re;
141 | }
142 | return new Complex(eval(reArgs), 0);
143 | }
144 | }
145 |
146 | public void checkArity(int nArgs) throws ArityException {
147 | if (arity() != nArgs) {
148 | throw new ArityException("Expected " + arity() + " arguments, got " + nArgs);
149 | }
150 | }
151 |
152 | }
153 |
--------------------------------------------------------------------------------
/arity/src/main/java/org/javia/arity/FunctionAndName.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2008 Mihai Preda.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.javia.arity;
18 |
19 | /**
20 | * Encapsulates together a function and its name.
21 | * Is used to return both the function and its name
22 | * from Compiler.compileWithName().
23 | */
24 |
25 | public class FunctionAndName {
26 | public Function function;
27 | public String name;
28 |
29 | public FunctionAndName(Function fun, String name) {
30 | this.function = fun;
31 | this.name = name;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/arity/src/main/java/org/javia/arity/FunctionStack.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2008-2009 Mihai Preda.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.javia.arity;
18 |
19 | class FunctionStack {
20 | private Function[] data = new Function[8];
21 | private int size = 0;
22 |
23 | void clear() {
24 | size = 0;
25 | }
26 |
27 | void push(Function b) {
28 | if (size >= data.length) {
29 | Function[] newData = new Function[data.length << 1];
30 | System.arraycopy(data, 0, newData, 0, data.length);
31 | data = newData;
32 | }
33 | data[size++] = b;
34 | }
35 |
36 | /*
37 | void pop(int cnt) {
38 | size -= cnt;
39 | }
40 | */
41 |
42 | Function pop() {
43 | return data[--size];
44 | }
45 |
46 | Function[] toArray() {
47 | Function[] trimmed = new Function[size];
48 | System.arraycopy(data, 0, trimmed, 0, size);
49 | return trimmed;
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/arity/src/main/java/org/javia/arity/IsComplexException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2009 Mihai Preda.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.javia.arity;
18 |
19 | class IsComplexException extends Exception {
20 | }
21 |
--------------------------------------------------------------------------------
/arity/src/main/java/org/javia/arity/OptCodeGen.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2007-2009 Mihai Preda.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.javia.arity;
18 |
19 | /* Optimizing Code Generator
20 | Reads tokens in RPN (Reverse Polish Notation) order,
21 | and generates VM opcodes,
22 | doing constant-folding optimization.
23 | */
24 |
25 | class OptCodeGen extends SimpleCodeGen {
26 | EvalContext context = new EvalContext();
27 | int sp;
28 | Complex stack[] = context.stackComplex;
29 |
30 | double traceConstsRe[] = new double[1];
31 | double traceConstsIm[] = new double[1];
32 | Function traceFuncs[] = new Function[1];
33 | byte traceCode[] = new byte[1];
34 | CompiledFunction tracer = new CompiledFunction(0, traceCode, traceConstsRe, traceConstsIm, traceFuncs);
35 |
36 | int intrinsicArity;
37 | private boolean isPercent;
38 |
39 | OptCodeGen(SyntaxException e) {
40 | super(e);
41 | }
42 |
43 | //@Override
44 | void start() {
45 | super.start();
46 | sp = -1;
47 | intrinsicArity = 0;
48 | isPercent = false;
49 | }
50 |
51 | //@Override
52 | void push(Token token) throws SyntaxException {
53 | // System.err.println("state " + getFun(0) + "; token " + token);
54 | final boolean prevWasPercent = isPercent;
55 | isPercent = false;
56 | byte op;
57 | switch (token.id) {
58 | case Lexer.NUMBER:
59 | op = VM.CONST;
60 | traceConstsRe[0] = token.value;
61 | traceConstsIm[0] = 0;
62 | break;
63 |
64 | case Lexer.CONST:
65 | case Lexer.CALL:
66 | Symbol symbol = getSymbol(token);
67 | if (token.isDerivative()) {
68 | op = VM.CALL;
69 | traceFuncs[0] = symbol.fun.getDerivative();
70 | } else if (symbol.op > 0) { // built-in
71 | op = symbol.op;
72 | if (op >= VM.LOAD0 && op <= VM.LOAD4) {
73 | int arg = op - VM.LOAD0;
74 | if (arg + 1 > intrinsicArity) {
75 | intrinsicArity = arg + 1;
76 | }
77 | stack[++sp].re = Double.NaN;
78 | stack[sp].im = 0;
79 | code.push(op);
80 | //System.out.println("op " + VM.opcodeName[op] + "; sp " + sp + "; top " + stack[sp]);
81 | return;
82 | }
83 | } else if (symbol.fun != null) { // function call
84 | op = VM.CALL;
85 | traceFuncs[0] = symbol.fun;
86 | } else { // variable reference
87 | op = VM.CONST;
88 | traceConstsRe[0] = symbol.valueRe;
89 | traceConstsIm[0] = symbol.valueIm;
90 | }
91 | break;
92 |
93 | default:
94 | op = token.vmop;
95 | if (op <= 0) {
96 | throw new Error("wrong vmop: " + op);
97 | }
98 | if (op == VM.PERCENT) {
99 | isPercent = true;
100 | }
101 | }
102 | int oldSP = sp;
103 | traceCode[0] = op;
104 | if (op != VM.RND) {
105 | sp = tracer.execWithoutCheckComplex(context, sp, prevWasPercent ? -1 : -2);
106 | } else {
107 | stack[++sp].re = Double.NaN;
108 | stack[sp].im = 0;
109 | }
110 |
111 | //System.out.println("op " + VM.opcodeName[op] + "; old " + oldSP + "; sp " + sp + "; top " + stack[sp] + " " + stack[0]);
112 |
113 | //constant folding
114 | if (!stack[sp].isNaN() || op == VM.CONST) {
115 | int nPopCode = op == VM.CALL ? traceFuncs[0].arity() : VM.arity[op];
116 | while (nPopCode > 0) {
117 | final byte pop = code.pop();
118 | if (pop == VM.CONST) {
119 | consts.pop();
120 | } else if (pop == VM.CALL) {
121 | Function f = funcs.pop();
122 | nPopCode += f.arity() - 1;
123 | } else {
124 | nPopCode += VM.arity[pop];
125 | }
126 | --nPopCode;
127 | }
128 | consts.push(stack[sp].re, stack[sp].im);
129 | op = VM.CONST;
130 | } else if (op == VM.CALL) {
131 | funcs.push(traceFuncs[0]);
132 | }
133 | code.push(op);
134 | }
135 |
136 | CompiledFunction getFun(int arity) {
137 | return new CompiledFunction(arity, code.toArray(), consts.getRe(), consts.getIm(), funcs.toArray());
138 | }
139 | }
140 |
--------------------------------------------------------------------------------
/arity/src/main/java/org/javia/arity/SimpleCodeGen.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2007-2008 Mihai Preda.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.javia.arity;
18 |
19 | /* Non-optimizing Code Generator
20 | Reads tokens in RPN (Reverse Polish Notation) order,
21 | and generates VM opcodes,
22 | without any optimization.
23 | */
24 |
25 | class SimpleCodeGen extends TokenConsumer {
26 | static final SyntaxException HAS_ARGUMENTS = new SyntaxException();
27 |
28 | ByteStack code = new ByteStack();
29 | DoubleStack consts = new DoubleStack();
30 | FunctionStack funcs = new FunctionStack();
31 |
32 | //String argNames[];
33 | Symbols symbols;
34 |
35 | SyntaxException exception;
36 |
37 | SimpleCodeGen(SyntaxException exception) {
38 | this.exception = exception;
39 | }
40 |
41 | SimpleCodeGen setSymbols(Symbols symbols) {
42 | this.symbols = symbols;
43 | return this;
44 | }
45 |
46 | //@Override
47 | void start() {
48 | code.clear();
49 | consts.clear();
50 | funcs.clear();
51 | }
52 |
53 | Symbol getSymbol(Token token) throws SyntaxException {
54 | String name = token.name;
55 | boolean isDerivative = token.isDerivative();
56 | if (isDerivative) {
57 | if (token.arity == 1) {
58 | name = name.substring(0, name.length() - 1);
59 | } else {
60 | throw exception.set("Derivative expects arity 1 but found " + token.arity, token.position);
61 | }
62 | }
63 | Symbol symbol = symbols.lookup(name, token.arity);
64 | if (symbol == null) {
65 | throw exception.set("undefined '" + name + "' with arity " + token.arity, token.position);
66 | }
67 | if (isDerivative && symbol.op > 0 && symbol.fun == null) {
68 | symbol.fun = CompiledFunction.makeOpFunction(symbol.op);
69 | }
70 | if (isDerivative && symbol.fun == null) {
71 | throw exception.set("Invalid derivative " + name, token.position);
72 | }
73 | return symbol;
74 | }
75 |
76 | void push(Token token) throws SyntaxException {
77 | byte op;
78 | switch (token.id) {
79 | case Lexer.NUMBER:
80 | op = VM.CONST;
81 | consts.push(token.value, 0);
82 | break;
83 |
84 | case Lexer.CONST:
85 | case Lexer.CALL:
86 | Symbol symbol = getSymbol(token);
87 | if (token.isDerivative()) {
88 | op = VM.CALL;
89 | funcs.push(symbol.fun.getDerivative());
90 | } else if (symbol.op > 0) { // built-in
91 | op = symbol.op;
92 | if (op >= VM.LOAD0 && op <= VM.LOAD4) {
93 | throw HAS_ARGUMENTS.set("eval() on implicit function", exception.position);
94 | }
95 | } else if (symbol.fun != null) { // function call
96 | op = VM.CALL;
97 | funcs.push(symbol.fun);
98 | } else { // variable reference
99 | op = VM.CONST;
100 | consts.push(symbol.valueRe, symbol.valueIm);
101 | }
102 | break;
103 |
104 | default:
105 | op = token.vmop;
106 | if (op <= 0) {
107 | throw new Error("wrong vmop: " + op + ", id " + token.id + " in \"" + exception.expression + '"');
108 | }
109 | }
110 | code.push(op);
111 | }
112 |
113 | CompiledFunction getFun() {
114 | return new CompiledFunction(0, code.toArray(), consts.getRe(), consts.getIm(), funcs.toArray());
115 | }
116 |
117 | /*
118 | double getValue() {
119 | return new CompiledFunction(0, code.toArray(), consts.getRe(), consts.getIm(), funcs.toArray()).eval();
120 | }
121 | */
122 | }
123 |
--------------------------------------------------------------------------------
/arity/src/main/java/org/javia/arity/Symbol.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2008 Mihai Preda.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.javia.arity;
18 |
19 | public class Symbol {
20 | static final int CONST_ARITY = -3;
21 | byte op;
22 | Function fun;
23 | double valueRe, valueIm;
24 | boolean isConst = false;
25 | private String name;
26 | private int arity;
27 |
28 | private Symbol(String name, int arity, byte op, boolean isConst, int dummy) {
29 | setKey(name, arity);
30 | this.op = op;
31 | this.isConst = isConst;
32 | }
33 |
34 | Symbol(String name, Function fun) {
35 | setKey(name, fun.arity());
36 | this.fun = fun;
37 | // this.comment = fun.comment;
38 | }
39 |
40 | Symbol(String name, double re, boolean isConst) {
41 | this(name, re, 0, isConst);
42 | }
43 |
44 | Symbol(String name, double re, double im, boolean isConst) {
45 | setKey(name, CONST_ARITY);
46 | valueRe = re;
47 | valueIm = im;
48 | this.isConst = isConst;
49 | }
50 |
51 | static Symbol makeArg(String name, int order) {
52 | return new Symbol(name, CONST_ARITY, (byte) (VM.LOAD0 + order), false, 0);
53 | }
54 |
55 | static Symbol makeVmOp(String name, int op) {
56 | return new Symbol(name, (int) VM.arity[op], (byte) op, true, 0);
57 | }
58 |
59 | static Symbol newEmpty(Symbol s) {
60 | return new Symbol(s.name, s.arity, (byte) 0, false, 0);
61 | }
62 |
63 | public String toString() {
64 | return "Symbol '" + name + "' arity " + arity + " val " + valueRe + " op " + op;
65 | }
66 |
67 | /*
68 | public String getComment() {
69 | return comment;
70 | }
71 | */
72 |
73 | public String getName() {
74 | return name;
75 | }
76 |
77 | public int getArity() {
78 | return arity == CONST_ARITY ? 0 : arity;
79 | }
80 |
81 | boolean isEmpty() {
82 | return op == 0 && fun == null && valueRe == 0 && valueIm == 0;
83 | }
84 |
85 | Symbol setKey(String name, int arity) {
86 | this.name = name;
87 | this.arity = arity;
88 | return this;
89 | }
90 |
91 | public boolean equals(Object other) {
92 | Symbol symbol = (Symbol) other;
93 | return name.equals(symbol.name) && arity == symbol.arity;
94 | }
95 |
96 | public int hashCode() {
97 | return name.hashCode() + arity;
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/arity/src/main/java/org/javia/arity/SyntaxException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2007-2008 Mihai Preda.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.javia.arity;
18 |
19 | /**
20 | * Thrown when the expression can't be compiled, because it's either not
21 | * well-formed (e.g. "1+"), or because some simbols aren't defined (e.g. "foo+2").
22 | */
23 | public class SyntaxException extends Exception {
24 | /**
25 | * The expression which caused the error.
26 | */
27 | public String expression;
28 |
29 | /**
30 | * Explicative message (cause of error).
31 | */
32 | public String message;
33 |
34 | /**
35 | * The position inside expression where the error occured.
36 | */
37 | public int position;
38 |
39 | public String toString() {
40 | return "SyntaxException: " + message
41 | + " in '" + expression
42 | + "' at position " + position;
43 | }
44 |
45 | SyntaxException set(String str, int pos) {
46 | message = str;
47 | position = pos;
48 | fillInStackTrace();
49 | return this;
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/arity/src/main/java/org/javia/arity/Token.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2007-2008 Mihai Preda.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.javia.arity;
18 |
19 | class Token {
20 | //kind
21 | static final int
22 | PREFIX = 1,
23 | LEFT = 2,
24 | RIGHT = 3,
25 | SUFIX = 4;
26 |
27 | final int priority;
28 | final int assoc;
29 | final int id;
30 | final byte vmop;
31 |
32 | double value; //for NUMBER only
33 | String name = null; //for CONST & CALL
34 | int arity;
35 | int position; //pos inside expression
36 |
37 | Token(int id, int priority, int assoc, int vmop) {
38 | this.id = id;
39 | this.priority = priority;
40 | this.assoc = assoc;
41 | this.vmop = (byte) vmop;
42 | arity = id == Lexer.CALL ? 1 : Symbol.CONST_ARITY;
43 | }
44 |
45 | Token setPos(int pos) {
46 | this.position = pos;
47 | return this;
48 | }
49 |
50 | Token setValue(double value) {
51 | this.value = value;
52 | return this;
53 | }
54 |
55 | Token setAlpha(String alpha) {
56 | name = alpha;
57 | return this;
58 | }
59 |
60 | public boolean isDerivative() {
61 | int len;
62 | return name != null && (len = name.length()) > 0 && name.charAt(len - 1) == '\'';
63 | }
64 |
65 | public String toString() {
66 | switch (id) {
67 | case Lexer.NUMBER:
68 | return "" + value;
69 | case Lexer.CALL:
70 | return name + '(' + arity + ')';
71 | case Lexer.CONST:
72 | return name;
73 | }
74 | return "" + id;
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/arity/src/main/java/org/javia/arity/TokenConsumer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2007-2008 Mihai Preda.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.javia.arity;
18 |
19 | abstract class TokenConsumer {
20 | void start() {
21 | }
22 |
23 | abstract void push(Token token) throws SyntaxException;
24 | }
25 |
--------------------------------------------------------------------------------
/arity/src/main/java/org/javia/arity/VM.java:
--------------------------------------------------------------------------------
1 | // This file is automatically generated by the build.py script. Do not edit!
2 |
3 | /*
4 | * Copyright (C) 2008-2009 Mihai Preda.
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 |
19 | package org.javia.arity;
20 |
21 | class VM {
22 |
23 | static final byte
24 | RESERVED = 0,
25 | CONST = 1,
26 | CALL = 2,
27 | ADD = 3,
28 | SUB = 4,
29 | MUL = 5,
30 | DIV = 6,
31 | MOD = 7,
32 | RND = 8,
33 | UMIN = 9,
34 | POWER = 10,
35 | FACT = 11,
36 | PERCENT = 12,
37 | SQRT = 13,
38 | CBRT = 14,
39 | EXP = 15,
40 | LN = 16,
41 | SIN = 17,
42 | COS = 18,
43 | TAN = 19,
44 | ASIN = 20,
45 | ACOS = 21,
46 | ATAN = 22,
47 | SINH = 23,
48 | COSH = 24,
49 | TANH = 25,
50 | ASINH = 26,
51 | ACOSH = 27,
52 | ATANH = 28,
53 | ABS = 29,
54 | FLOOR = 30,
55 | CEIL = 31,
56 | SIGN = 32,
57 | MIN = 33,
58 | MAX = 34,
59 | GCD = 35,
60 | COMB = 36,
61 | PERM = 37,
62 | LOAD0 = 38,
63 | LOAD1 = 39,
64 | LOAD2 = 40,
65 | LOAD3 = 41,
66 | LOAD4 = 42,
67 | REAL = 43,
68 | IMAG = 44;
69 |
70 | static final String[] opcodeName = {"reserved", "const", "call", "add", "sub", "mul", "div", "mod", "rnd", "umin", "power", "fact", "percent", "sqrt", "cbrt", "exp", "ln", "sin", "cos", "tan", "asin", "acos", "atan", "sinh", "cosh", "tanh", "asinh", "acosh", "atanh", "abs", "floor", "ceil", "sign", "min", "max", "gcd", "comb", "perm", "load0", "load1", "load2", "load3", "load4", "real", "imag"};
71 |
72 | static final byte[] arity = {0, 0, -1, 2, 2, 2, 2, 2, 0, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 1, 1};
73 |
74 | static final byte[] builtins = {RND, SQRT, CBRT, SIN, COS, TAN, ASIN, ACOS, ATAN, SINH, COSH, TANH, ASINH, ACOSH, ATANH, EXP, LN, ABS, FLOOR, CEIL, SIGN, MIN, MAX, GCD, COMB, PERM, MOD, REAL, IMAG};
75 |
76 | }
77 |
--------------------------------------------------------------------------------
/build.gradle.kts:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 | plugins {
3 | id("com.android.application") version "8.1.2" apply false
4 | id("org.jetbrains.kotlin.android") version "1.8.21" apply false
5 | id("org.jetbrains.kotlin.jvm") version "1.8.21" apply false
6 | }
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/full_description.txt:
--------------------------------------------------------------------------------
1 | CalcYou is a privacy focused calculator app that is not just a calculator.
2 | Solve everyday problems with the intuitive basic calculator, or delve into advanced functions with the powerful scientific calculator.
3 | Feeling lost in a sea of units? CalcYou's versatile converter effortlessly handles length, weight, volume, and more.
4 | Need to express complex equations? Access a vast library of symbols, including Greek letters, arrows, superscript, and subscript, all with a few taps.
5 | CalcYou's elegant interface, history function, and customizable themes make calculations a breeze, whether you're a student, engineer, scientist, or anyone who loves the power of numbers.
6 |
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/images/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/you-apps/CalcYou/8e61a0bf33783a51a90ad0e9b6068e4fd43fa233/fastlane/metadata/android/en-US/images/icon.png
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/you-apps/CalcYou/8e61a0bf33783a51a90ad0e9b6068e4fd43fa233/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/images/phoneScreenshots/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/you-apps/CalcYou/8e61a0bf33783a51a90ad0e9b6068e4fd43fa233/fastlane/metadata/android/en-US/images/phoneScreenshots/2.png
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/images/phoneScreenshots/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/you-apps/CalcYou/8e61a0bf33783a51a90ad0e9b6068e4fd43fa233/fastlane/metadata/android/en-US/images/phoneScreenshots/3.png
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/images/phoneScreenshots/4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/you-apps/CalcYou/8e61a0bf33783a51a90ad0e9b6068e4fd43fa233/fastlane/metadata/android/en-US/images/phoneScreenshots/4.png
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/images/phoneScreenshots/5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/you-apps/CalcYou/8e61a0bf33783a51a90ad0e9b6068e4fd43fa233/fastlane/metadata/android/en-US/images/phoneScreenshots/5.png
--------------------------------------------------------------------------------
/fastlane/metadata/android/en-US/short_description.txt:
--------------------------------------------------------------------------------
1 | Privacy Focused Calculator app built with MD3
2 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 | # AndroidX package structure to make it clearer which packages are bundled with the
15 | # Android operating system, and which are packaged with your app's APK
16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
17 | android.useAndroidX=true
18 | # Kotlin code style for this project: "official" or "obsolete":
19 | kotlin.code.style=official
20 | # Enables namespacing of each library's R class so that its R class includes only the
21 | # resources declared in the library itself and none from the library's dependencies,
22 | # thereby reducing the size of the R class for that library
23 | android.nonTransitiveRClass=true
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/you-apps/CalcYou/8e61a0bf33783a51a90ad0e9b6068e4fd43fa233/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
4 | networkTimeout=10000
5 | validateDistributionUrl=true
6 | zipStoreBase=GRADLE_USER_HOME
7 | zipStorePath=wrapper/dists
8 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 | @rem SPDX-License-Identifier: Apache-2.0
17 | @rem
18 |
19 | @if "%DEBUG%"=="" @echo off
20 | @rem ##########################################################################
21 | @rem
22 | @rem Gradle startup script for Windows
23 | @rem
24 | @rem ##########################################################################
25 |
26 | @rem Set local scope for the variables with windows NT shell
27 | if "%OS%"=="Windows_NT" setlocal
28 |
29 | set DIRNAME=%~dp0
30 | if "%DIRNAME%"=="" set DIRNAME=.
31 | @rem This is normally unused
32 | set APP_BASE_NAME=%~n0
33 | set APP_HOME=%DIRNAME%
34 |
35 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
36 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
37 |
38 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
39 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
40 |
41 | @rem Find java.exe
42 | if defined JAVA_HOME goto findJavaFromJavaHome
43 |
44 | set JAVA_EXE=java.exe
45 | %JAVA_EXE% -version >NUL 2>&1
46 | if %ERRORLEVEL% equ 0 goto execute
47 |
48 | echo. 1>&2
49 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
50 | echo. 1>&2
51 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2
52 | echo location of your Java installation. 1>&2
53 |
54 | goto fail
55 |
56 | :findJavaFromJavaHome
57 | set JAVA_HOME=%JAVA_HOME:"=%
58 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
59 |
60 | if exist "%JAVA_EXE%" goto execute
61 |
62 | echo. 1>&2
63 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
64 | echo. 1>&2
65 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2
66 | echo location of your Java installation. 1>&2
67 |
68 | goto fail
69 |
70 | :execute
71 | @rem Setup the command line
72 |
73 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
74 |
75 |
76 | @rem Execute Gradle
77 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
78 |
79 | :end
80 | @rem End local scope for the variables with windows NT shell
81 | if %ERRORLEVEL% equ 0 goto mainEnd
82 |
83 | :fail
84 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
85 | rem the _cmd.exe /c_ return code!
86 | set EXIT_CODE=%ERRORLEVEL%
87 | if %EXIT_CODE% equ 0 set EXIT_CODE=1
88 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
89 | exit /b %EXIT_CODE%
90 |
91 | :mainEnd
92 | if "%OS%"=="Windows_NT" endlocal
93 |
94 | :omega
95 |
--------------------------------------------------------------------------------
/settings.gradle.kts:
--------------------------------------------------------------------------------
1 | pluginManagement {
2 | repositories {
3 | google()
4 | mavenCentral()
5 | gradlePluginPortal()
6 | }
7 | }
8 | dependencyResolutionManagement {
9 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
10 | repositories {
11 | google()
12 | mavenCentral()
13 | }
14 | }
15 |
16 | rootProject.name = "CalcYou"
17 | include(":app")
18 | include(":arity")
19 |
--------------------------------------------------------------------------------