├── linux
├── .gitignore
├── main.cc
├── flutter
│ ├── generated_plugin_registrant.h
│ ├── generated_plugin_registrant.cc
│ ├── generated_plugins.cmake
│ └── CMakeLists.txt
├── my_application.h
├── my_application.cc
└── CMakeLists.txt
├── ios
├── Flutter
│ ├── Debug.xcconfig
│ ├── Release.xcconfig
│ └── AppFrameworkInfo.plist
├── Runner
│ ├── Runner-Bridging-Header.h
│ ├── Assets.xcassets
│ │ ├── LaunchImage.imageset
│ │ │ ├── LaunchImage.png
│ │ │ ├── LaunchImage@2x.png
│ │ │ ├── LaunchImage@3x.png
│ │ │ ├── README.md
│ │ │ └── Contents.json
│ │ └── AppIcon.appiconset
│ │ │ ├── Icon-App-20x20@1x.png
│ │ │ ├── Icon-App-20x20@2x.png
│ │ │ ├── Icon-App-20x20@3x.png
│ │ │ ├── Icon-App-29x29@1x.png
│ │ │ ├── Icon-App-29x29@2x.png
│ │ │ ├── Icon-App-29x29@3x.png
│ │ │ ├── Icon-App-40x40@1x.png
│ │ │ ├── Icon-App-40x40@2x.png
│ │ │ ├── Icon-App-40x40@3x.png
│ │ │ ├── Icon-App-60x60@2x.png
│ │ │ ├── Icon-App-60x60@3x.png
│ │ │ ├── Icon-App-76x76@1x.png
│ │ │ ├── Icon-App-76x76@2x.png
│ │ │ ├── Icon-App-1024x1024@1x.png
│ │ │ ├── Icon-App-83.5x83.5@2x.png
│ │ │ └── Contents.json
│ ├── AppDelegate.swift
│ ├── Base.lproj
│ │ ├── Main.storyboard
│ │ └── LaunchScreen.storyboard
│ └── Info.plist
├── Runner.xcodeproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ ├── WorkspaceSettings.xcsettings
│ │ │ └── IDEWorkspaceChecks.plist
│ └── xcshareddata
│ │ └── xcschemes
│ │ └── Runner.xcscheme
├── Runner.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ ├── WorkspaceSettings.xcsettings
│ │ └── IDEWorkspaceChecks.plist
└── .gitignore
├── Peek-parsing.gif
├── Peek-semantic.gif
├── peek-lexical.gif
├── graphite_modify.png
├── InterpreterVisualizer
├── src
│ ├── main
│ │ ├── resources
│ │ │ └── application.properties
│ │ └── java
│ │ │ ├── simpleinterpreter
│ │ │ ├── RuntimeError.java
│ │ │ ├── TokenType.java
│ │ │ ├── Environment.java
│ │ │ ├── InterpreterAdapter.java
│ │ │ ├── Token.java
│ │ │ ├── Stmt.java
│ │ │ ├── Expr.java
│ │ │ ├── SimpleInterpreter.java
│ │ │ ├── StatementGraph.java
│ │ │ ├── Scanner.java
│ │ │ └── AST.java
│ │ │ └── api
│ │ │ └── interpretervisualizer
│ │ │ ├── InterpreterVisualizerAPI.java
│ │ │ └── controller
│ │ │ └── WebController.java
│ └── test
│ │ └── java
│ │ └── api
│ │ └── interpretervisualizer
│ │ └── InterpreterVisualizerApplicationTests.java
├── .mvn
│ └── wrapper
│ │ ├── maven-wrapper.jar
│ │ ├── maven-wrapper.properties
│ │ └── MavenWrapperDownloader.java
├── .gitignore
├── pom.xml
└── mvnw.cmd
├── peek-hello-lexical.gif
├── peek-lexical-error.gif
├── peek-hello-semantic.gif
├── android
├── gradle.properties
├── app
│ ├── src
│ │ ├── main
│ │ │ ├── res
│ │ │ │ ├── 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
│ │ │ │ ├── drawable
│ │ │ │ │ └── launch_background.xml
│ │ │ │ ├── drawable-v21
│ │ │ │ │ └── launch_background.xml
│ │ │ │ ├── values
│ │ │ │ │ └── styles.xml
│ │ │ │ └── values-night
│ │ │ │ │ └── styles.xml
│ │ │ ├── java
│ │ │ │ └── com
│ │ │ │ │ └── example
│ │ │ │ │ └── flutterdesktopapp
│ │ │ │ │ └── MainActivity.java
│ │ │ └── AndroidManifest.xml
│ │ ├── debug
│ │ │ └── AndroidManifest.xml
│ │ └── profile
│ │ │ └── AndroidManifest.xml
│ └── build.gradle
├── gradle
│ └── wrapper
│ │ └── gradle-wrapper.properties
├── .gitignore
├── settings.gradle
└── build.gradle
├── lib
├── main.dart
├── components
│ ├── snackbar.dart
│ └── resusable_circle.dart
├── ui_elements
│ ├── card_box.dart
│ ├── colored_card_box.dart
│ ├── text_highlighter.dart
│ ├── symbo_table_item.dart
│ ├── code_text.dart
│ ├── modes_circles.dart
│ ├── console_panel.dart
│ ├── symbol_table.dart
│ ├── freescrollview.dart
│ ├── token_item.dart
│ ├── single_graph.dart
│ └── control_buttons.dart
├── utils
│ ├── graphs_provider.dart
│ ├── utilities_provider.dart
│ ├── constants.dart
│ └── app_data.dart
├── models
│ ├── parsing_ast.dart
│ ├── response.dart
│ ├── Ast.dart
│ ├── tokens.dart
│ └── statement.dart
├── screens
│ ├── first_page.dart
│ ├── material_main_page.dart
│ ├── select_visualization_mode.dart
│ ├── tokens_page.dart
│ ├── home_page.dart
│ ├── ast_graph.dart
│ ├── parsing_ast_page.dart
│ ├── syntactic_and_statement_page.dart
│ └── semantic_page.dart
└── services
│ └── networking.dart
├── .metadata
├── assets
└── tokens_file.txt
├── .gitignore
├── test
└── widget_test.dart
├── LoxGrammar
├── contribution.md
├── pubspec.yaml
└── README.md
/linux/.gitignore:
--------------------------------------------------------------------------------
1 | flutter/ephemeral
2 |
--------------------------------------------------------------------------------
/ios/Flutter/Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Generated.xcconfig"
2 |
--------------------------------------------------------------------------------
/ios/Flutter/Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Generated.xcconfig"
2 |
--------------------------------------------------------------------------------
/ios/Runner/Runner-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | #import "GeneratedPluginRegistrant.h"
2 |
--------------------------------------------------------------------------------
/Peek-parsing.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OsamaMaani/Interpreter-Visualizer/HEAD/Peek-parsing.gif
--------------------------------------------------------------------------------
/Peek-semantic.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OsamaMaani/Interpreter-Visualizer/HEAD/Peek-semantic.gif
--------------------------------------------------------------------------------
/peek-lexical.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OsamaMaani/Interpreter-Visualizer/HEAD/peek-lexical.gif
--------------------------------------------------------------------------------
/graphite_modify.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OsamaMaani/Interpreter-Visualizer/HEAD/graphite_modify.png
--------------------------------------------------------------------------------
/InterpreterVisualizer/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | server.port=9090
2 | server.address=192.168.1.5
--------------------------------------------------------------------------------
/peek-hello-lexical.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OsamaMaani/Interpreter-Visualizer/HEAD/peek-hello-lexical.gif
--------------------------------------------------------------------------------
/peek-lexical-error.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OsamaMaani/Interpreter-Visualizer/HEAD/peek-lexical-error.gif
--------------------------------------------------------------------------------
/peek-hello-semantic.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OsamaMaani/Interpreter-Visualizer/HEAD/peek-hello-semantic.gif
--------------------------------------------------------------------------------
/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx1536M
2 | android.useAndroidX=true
3 | android.enableJetifier=true
4 |
--------------------------------------------------------------------------------
/InterpreterVisualizer/.mvn/wrapper/maven-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OsamaMaani/Interpreter-Visualizer/HEAD/InterpreterVisualizer/.mvn/wrapper/maven-wrapper.jar
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OsamaMaani/Interpreter-Visualizer/HEAD/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OsamaMaani/Interpreter-Visualizer/HEAD/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OsamaMaani/Interpreter-Visualizer/HEAD/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OsamaMaani/Interpreter-Visualizer/HEAD/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OsamaMaani/Interpreter-Visualizer/HEAD/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/lib/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutterdesktopapp/screens/material_main_page.dart';
3 |
4 | void main() {
5 | runApp(MyApp());
6 | }
7 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OsamaMaani/Interpreter-Visualizer/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
--------------------------------------------------------------------------------
/android/app/src/main/java/com/example/flutterdesktopapp/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.example.flutterdesktopapp;
2 |
3 |
4 | public class MainActivity extends FlutterActivity {
5 |
6 | }
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OsamaMaani/Interpreter-Visualizer/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OsamaMaani/Interpreter-Visualizer/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OsamaMaani/Interpreter-Visualizer/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OsamaMaani/Interpreter-Visualizer/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OsamaMaani/Interpreter-Visualizer/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OsamaMaani/Interpreter-Visualizer/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OsamaMaani/Interpreter-Visualizer/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OsamaMaani/Interpreter-Visualizer/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OsamaMaani/Interpreter-Visualizer/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OsamaMaani/Interpreter-Visualizer/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OsamaMaani/Interpreter-Visualizer/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OsamaMaani/Interpreter-Visualizer/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OsamaMaani/Interpreter-Visualizer/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OsamaMaani/Interpreter-Visualizer/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OsamaMaani/Interpreter-Visualizer/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OsamaMaani/Interpreter-Visualizer/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OsamaMaani/Interpreter-Visualizer/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
--------------------------------------------------------------------------------
/linux/main.cc:
--------------------------------------------------------------------------------
1 | #include "my_application.h"
2 |
3 | int main(int argc, char** argv) {
4 | g_autoptr(MyApplication) app = my_application_new();
5 | return g_application_run(G_APPLICATION(app), argc, argv);
6 | }
7 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/InterpreterVisualizer/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.1/apache-maven-3.8.1-bin.zip
2 | wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar
3 |
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Fri Jun 23 08:50:38 CEST 2017
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip
7 |
--------------------------------------------------------------------------------
/InterpreterVisualizer/src/main/java/simpleinterpreter/RuntimeError.java:
--------------------------------------------------------------------------------
1 | package simpleinterpreter;
2 |
3 | class RuntimeError extends RuntimeException {
4 | final Token token;
5 |
6 | RuntimeError(Token token, String message) {
7 | super(message);
8 | this.token = token;
9 | }
10 | }
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/android/.gitignore:
--------------------------------------------------------------------------------
1 | gradle-wrapper.jar
2 | /.gradle
3 | /captures/
4 | /gradlew
5 | /gradlew.bat
6 | /local.properties
7 | GeneratedPluginRegistrant.java
8 |
9 | # Remember to never publicly share your keystore.
10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
11 | key.properties
12 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/lib/components/snackbar.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class SnackBarMessage extends StatelessWidget {
4 | String path;
5 | SnackBarMessage(this.path);
6 |
7 | @override
8 | Widget build(BuildContext context) {
9 | return SnackBar(
10 | content: Text('Graph is saved to $path'),
11 | );
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/.metadata:
--------------------------------------------------------------------------------
1 | # This file tracks properties of this Flutter project.
2 | # Used by Flutter tool to assess capabilities and perform upgrades etc.
3 | #
4 | # This file should be version controlled and should not be manually edited.
5 |
6 | version:
7 | revision: b1395592de68cc8ac4522094ae59956dd21a91db
8 | channel: stable
9 |
10 | project_type: app
11 |
--------------------------------------------------------------------------------
/linux/flutter/generated_plugin_registrant.h:
--------------------------------------------------------------------------------
1 | //
2 | // Generated file. Do not edit.
3 | //
4 |
5 | #ifndef GENERATED_PLUGIN_REGISTRANT_
6 | #define GENERATED_PLUGIN_REGISTRANT_
7 |
8 | #include
9 |
10 | // Registers Flutter plugins.
11 | void fl_register_plugins(FlPluginRegistry* registry);
12 |
13 | #endif // GENERATED_PLUGIN_REGISTRANT_
14 |
--------------------------------------------------------------------------------
/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/android/app/src/profile/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/InterpreterVisualizer/src/test/java/api/interpretervisualizer/InterpreterVisualizerApplicationTests.java:
--------------------------------------------------------------------------------
1 | package api.interpretervisualizer;
2 |
3 | import org.junit.jupiter.api.Test;
4 | import org.springframework.boot.test.context.SpringBootTest;
5 |
6 | @SpringBootTest
7 | class InterpreterVisualizerApplicationTests {
8 |
9 | @Test
10 | void contextLoads() {
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md:
--------------------------------------------------------------------------------
1 | # Launch Screen Assets
2 |
3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory.
4 |
5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.
--------------------------------------------------------------------------------
/assets/tokens_file.txt:
--------------------------------------------------------------------------------
1 | VAR,var,null,1,0,2,4
2 | IDENTIFIER,x,null,1,4,4,3
3 | EQUAL,=,null,1,6,6,2
4 | NUMBER,3,3.0,1,8,8,3
5 | SEMICOLON,;,null,1,9,9,1
6 | VAR,var,null,2,12,14,4
7 | IDENTIFIER,y,null,2,16,16,3
8 | EQUAL,=,null,2,18,18,2
9 | NUMBER,10,10.0,2,20,21,3
10 | SEMICOLON,;,null,2,22,22,1
11 | PRINT,print,null,3,25,29,4
12 | NUMBER,5,5.0,3,31,31,3
13 | PLUS,+,null,3,33,33,1
14 | NUMBER,3,3.0,3,35,35,3
15 | SEMICOLON,;,null,3,36,36,1
16 | EOF,,null,3,37,37,0
--------------------------------------------------------------------------------
/ios/Runner/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 | import Flutter
3 |
4 | @UIApplicationMain
5 | @objc class AppDelegate: FlutterAppDelegate {
6 | override func application(
7 | _ application: UIApplication,
8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
9 | ) -> Bool {
10 | GeneratedPluginRegistrant.register(with: self)
11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions)
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/linux/flutter/generated_plugin_registrant.cc:
--------------------------------------------------------------------------------
1 | //
2 | // Generated file. Do not edit.
3 | //
4 |
5 | #include "generated_plugin_registrant.h"
6 |
7 | #include
8 |
9 | void fl_register_plugins(FlPluginRegistry* registry) {
10 | g_autoptr(FlPluginRegistrar) window_size_registrar =
11 | fl_plugin_registry_get_registrar_for_plugin(registry, "WindowSizePlugin");
12 | window_size_plugin_register_with_registrar(window_size_registrar);
13 | }
14 |
--------------------------------------------------------------------------------
/linux/my_application.h:
--------------------------------------------------------------------------------
1 | #ifndef FLUTTER_MY_APPLICATION_H_
2 | #define FLUTTER_MY_APPLICATION_H_
3 |
4 | #include
5 |
6 | G_DECLARE_FINAL_TYPE(MyApplication, my_application, MY, APPLICATION,
7 | GtkApplication)
8 |
9 | /**
10 | * my_application_new:
11 | *
12 | * Creates a new Flutter-based application.
13 | *
14 | * Returns: a new #MyApplication.
15 | */
16 | MyApplication* my_application_new();
17 |
18 | #endif // FLUTTER_MY_APPLICATION_H_
19 |
--------------------------------------------------------------------------------
/InterpreterVisualizer/src/main/java/api/interpretervisualizer/InterpreterVisualizerAPI.java:
--------------------------------------------------------------------------------
1 | package api.interpretervisualizer;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 |
6 | @SpringBootApplication
7 | public class InterpreterVisualizerAPI {
8 |
9 | public static void main(String[] args) {
10 |
11 | SpringApplication.run(InterpreterVisualizerAPI.class, args);
12 | }
13 |
14 | }
15 |
--------------------------------------------------------------------------------
/android/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
3 | def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
4 | def properties = new Properties()
5 |
6 | assert localPropertiesFile.exists()
7 | localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
8 |
9 | def flutterSdkPath = properties.getProperty("flutter.sdk")
10 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
11 | apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
12 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-v21/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "LaunchImage.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "LaunchImage@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "LaunchImage@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/InterpreterVisualizer/.gitignore:
--------------------------------------------------------------------------------
1 | HELP.md
2 | target/
3 | !.mvn/wrapper/maven-wrapper.jar
4 | !**/src/main/**/target/
5 | !**/src/test/**/target/
6 |
7 | ### STS ###
8 | .apt_generated
9 | .classpath
10 | .factorypath
11 | .project
12 | .settings
13 | .springBeans
14 | .sts4-cache
15 |
16 | ### IntelliJ IDEA ###
17 | .idea
18 | *.iws
19 | *.iml
20 | *.ipr
21 |
22 | ### NetBeans ###
23 | /nbproject/private/
24 | /nbbuild/
25 | /dist/
26 | /nbdist/
27 | /.nb-gradle/
28 | build/
29 | !**/src/main/**/build/
30 | !**/src/test/**/build/
31 |
32 | ### VS Code ###
33 | .vscode/
34 |
--------------------------------------------------------------------------------
/linux/flutter/generated_plugins.cmake:
--------------------------------------------------------------------------------
1 | #
2 | # Generated file, do not edit.
3 | #
4 |
5 | list(APPEND FLUTTER_PLUGIN_LIST
6 | window_size
7 | )
8 |
9 | set(PLUGIN_BUNDLED_LIBRARIES)
10 |
11 | foreach(plugin ${FLUTTER_PLUGIN_LIST})
12 | add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/linux plugins/${plugin})
13 | target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin)
14 | list(APPEND PLUGIN_BUNDLED_LIBRARIES $)
15 | list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries})
16 | endforeach(plugin)
17 |
--------------------------------------------------------------------------------
/InterpreterVisualizer/src/main/java/simpleinterpreter/TokenType.java:
--------------------------------------------------------------------------------
1 | package simpleinterpreter;
2 |
3 | enum TokenType {
4 | // Single-character tokens.
5 | LEFT_PAREN, RIGHT_PAREN, LEFT_BRACE, RIGHT_BRACE,
6 | COMMA, DOT, MINUS, PLUS, SEMICOLON, SLASH, STAR,
7 |
8 | // One or two character tokens.
9 | BANG, BANG_EQUAL,
10 | EQUAL, EQUAL_EQUAL,
11 | GREATER, GREATER_EQUAL,
12 | LESS, LESS_EQUAL,
13 |
14 | // Liter
15 | // als.
16 | IDENTIFIER, STRING, NUMBER,
17 |
18 | // Keywords.
19 | AND, CLASS, ELSE, FALSE, FUN, FOR, IF, NIL, OR,
20 | PRINT, RETURN, SUPER, THIS, TRUE, VAR, WHILE,
21 |
22 | EOF
23 | }
--------------------------------------------------------------------------------
/ios/.gitignore:
--------------------------------------------------------------------------------
1 | *.mode1v3
2 | *.mode2v3
3 | *.moved-aside
4 | *.pbxuser
5 | *.perspectivev3
6 | **/*sync/
7 | .sconsign.dblite
8 | .tags*
9 | **/.vagrant/
10 | **/DerivedData/
11 | Icon?
12 | **/Pods/
13 | **/.symlinks/
14 | profile
15 | xcuserdata
16 | **/.generated/
17 | Flutter/App.framework
18 | Flutter/Flutter.framework
19 | Flutter/Flutter.podspec
20 | Flutter/Generated.xcconfig
21 | Flutter/app.flx
22 | Flutter/app.zip
23 | Flutter/flutter_assets/
24 | Flutter/flutter_export_environment.sh
25 | ServiceDefinitions.json
26 | Runner/GeneratedPluginRegistrant.*
27 |
28 | # Exceptions to above rules.
29 | !default.mode1v3
30 | !default.mode2v3
31 | !default.pbxuser
32 | !default.perspectivev3
33 |
--------------------------------------------------------------------------------
/lib/ui_elements/card_box.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class CardBox extends StatelessWidget {
4 | final Widget child;
5 |
6 | CardBox({this.child});
7 |
8 | @override
9 | Widget build(BuildContext context) {
10 | return Container(
11 | child: Card(
12 | child: Padding(
13 | padding: const EdgeInsets.all(5.0),
14 | child: child,
15 | ),
16 | elevation: 1.0,
17 | shape: RoundedRectangleBorder(
18 | borderRadius: BorderRadius.circular(10.0),
19 | side: BorderSide(
20 | color: Colors.blue,
21 | width: 3,
22 | ),
23 | ),
24 | ),
25 | );
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | ext.kotlin_version = '1.3.50'
3 | repositories {
4 | google()
5 | jcenter()
6 | }
7 |
8 | dependencies {
9 | classpath 'com.android.tools.build:gradle:4.1.0'
10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
11 | }
12 | }
13 |
14 | allprojects {
15 | repositories {
16 | google()
17 | jcenter()
18 | }
19 | }
20 |
21 | rootProject.buildDir = '../build'
22 | subprojects {
23 | project.buildDir = "${rootProject.buildDir}/${project.name}"
24 | }
25 | subprojects {
26 | project.evaluationDependsOn(':app')
27 | }
28 |
29 | task clean(type: Delete) {
30 | delete rootProject.buildDir
31 | }
32 |
--------------------------------------------------------------------------------
/lib/ui_elements/colored_card_box.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class ColoredCardBox extends StatelessWidget {
4 | final Widget child;
5 | final Color color;
6 |
7 | ColoredCardBox({this.child, this.color});
8 |
9 | @override
10 | Widget build(BuildContext context) {
11 | return Container(
12 | child: Card(
13 | color: color,
14 | child: Padding(
15 | padding: const EdgeInsets.all(5.0),
16 | child: child,
17 | ),
18 | elevation: 1.0,
19 | shape: RoundedRectangleBorder(
20 | borderRadius: BorderRadius.circular(10.0),
21 | side: BorderSide(
22 | color: Colors.blue,
23 | width: 3,
24 | ),
25 | ),
26 | ),
27 | );
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/lib/utils/graphs_provider.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/cupertino.dart';
2 | import 'package:flutter/material.dart';
3 |
4 | class GraphProvider with ChangeNotifier {
5 | int _visualizedGraphIndex = 0;
6 | int _visualizedStatementIndex = 0;
7 | int _visualizedStepIndex = 0;
8 |
9 | int get visualizedStatementIndex => _visualizedStatementIndex;
10 |
11 | set visualizedStatementIndex(int value) {
12 | _visualizedStatementIndex = value;
13 | notifyListeners();
14 | }
15 |
16 | set visualizedGraphIndex(int value) {
17 | _visualizedGraphIndex = value;
18 | notifyListeners();
19 | }
20 |
21 | int get visualizedGraphIndex => _visualizedGraphIndex;
22 |
23 | int get visualizedStepIndex => _visualizedStepIndex;
24 |
25 | set visualizedStepIndex(int value) {
26 | _visualizedStepIndex = value;
27 | notifyListeners();
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/lib/models/parsing_ast.dart:
--------------------------------------------------------------------------------
1 | class ParsingAst {
2 | List _nodesData;
3 | List _graphs;
4 | List _visitedNode;
5 |
6 | ParsingAst(this._nodesData, this._graphs, this._visitedNode);
7 |
8 | factory ParsingAst.fromJson(Map json) {
9 | List nodesData = (json["Nodes"] as List);
10 |
11 | List graphs = (json["Graphs"] as List);
12 |
13 | List visitedNodes = (json["Visited Nodes"] as List);
14 |
15 | return ParsingAst(nodesData, graphs, visitedNodes);
16 | }
17 |
18 | set nodesData(List value) {
19 | _nodesData = value;
20 | }
21 |
22 | List get nodesData => _nodesData;
23 |
24 | List get graphs => _graphs;
25 |
26 | List get visitedNode => _visitedNode;
27 |
28 | set graphs(List value) {
29 | _graphs = value;
30 | }
31 |
32 | set visitedNode(List value) {
33 | _visitedNode = value;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/ios/Flutter/AppFrameworkInfo.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | App
9 | CFBundleIdentifier
10 | io.flutter.flutter.app
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | App
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1.0
23 | MinimumOSVersion
24 | 8.0
25 |
26 |
27 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Miscellaneous
2 | *.class
3 | *.log
4 | *.pyc
5 | *.swp
6 | .DS_Store
7 | .atom/
8 | .buildlog/
9 | .history
10 | .svn/
11 |
12 | # IntelliJ related
13 | *.iml
14 | *.ipr
15 | *.iws
16 | .idea/
17 |
18 | # The .vscode folder contains launch configuration and tasks you configure in
19 | # VS Code which you may wish to be included in version control, so this line
20 | # is commented out by default.
21 | #.vscode/
22 |
23 | # Flutter/Dart/Pub related
24 | **/doc/api/
25 | **/ios/Flutter/.last_build_id
26 | .dart_tool/
27 | .flutter-plugins
28 | .flutter-plugins-dependencies
29 | .packages
30 | .pub-cache/
31 | .pub/
32 | /build/
33 |
34 | # Web related
35 | lib/generated_plugin_registrant.dart
36 |
37 | # Symbolication related
38 | app.*.symbols
39 |
40 | # Obfuscation related
41 | app.*.map.json
42 |
43 | # Android Studio will place build artifacts here
44 | /android/app/debug
45 | /android/app/profile
46 | /android/app/release
47 |
--------------------------------------------------------------------------------
/lib/ui_elements/text_highlighter.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutterdesktopapp/utils/utilities_provider.dart';
3 | import 'package:provider/provider.dart';
4 |
5 | class TextHighlighter extends StatefulWidget {
6 | @override
7 | _TextHighlighterState createState() => _TextHighlighterState();
8 | }
9 |
10 | class _TextHighlighterState extends State {
11 | @override
12 | Widget build(BuildContext context) {
13 | final utilsProvider = Provider.of(context);
14 | var list = utilsProvider.richTextList;
15 |
16 | return Container(
17 | child: RichText(
18 | text: TextSpan(
19 | children: list.map((e) {
20 | return TextSpan(
21 | text: e[0],
22 | style: TextStyle(
23 | backgroundColor: e[1],
24 | fontSize: 30,
25 | fontWeight: FontWeight.bold));
26 | }).toList())),
27 | );
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/android/app/src/main/res/values-night/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/lib/screens/first_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutterdesktopapp/utils/app_data.dart';
3 | import 'package:provider/provider.dart';
4 |
5 | import '../ui_elements/modes_circles.dart';
6 |
7 | class PageOne extends StatelessWidget {
8 | const PageOne({Key key}) : super(key: key);
9 |
10 | @override
11 | Widget build(BuildContext context) {
12 | final appData = Provider.of(context);
13 | bool syntaxError = appData.astsList.length == 0;
14 |
15 | return Column(
16 | mainAxisAlignment: MainAxisAlignment.center,
17 | children: [
18 | ThreeCircles(
19 | headline1: "1",
20 | title1: "Lexical Analysis",
21 | function1: appData.changeCircleOneState,
22 | headline2: "2",
23 | title2: "Syntactic Analysis",
24 | function2: appData.changeCircleTwoState,
25 | headline3: "3",
26 | title3: "Semantic Analysis & Execution",
27 | function3: (syntaxError ? null : appData.changeCircleThreeState),
28 | ),
29 | ],
30 | );
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/test/widget_test.dart:
--------------------------------------------------------------------------------
1 | // This is a basic Flutter widget test.
2 | //
3 | // To perform an interaction with a widget in your test, use the WidgetTester
4 | // utility that Flutter provides. For example, you can send tap and scroll
5 | // gestures. You can also use WidgetTester to find child widgets in the widget
6 | // tree, read text, and verify that the values of widget properties are correct.
7 |
8 | import 'package:flutter/material.dart';
9 | import 'package:flutter_test/flutter_test.dart';
10 |
11 | import 'package:flutterdesktopapp/main.dart';
12 |
13 | void main() {
14 | testWidgets('Counter increments smoke test', (WidgetTester tester) async {
15 | // Build our app and trigger a frame.
16 | // await tester.pumpWidget(MyApp());
17 |
18 | // Verify that our counter starts at 0.
19 | expect(find.text('0'), findsOneWidget);
20 | expect(find.text('1'), findsNothing);
21 |
22 | // Tap the '+' icon and trigger a frame.
23 | await tester.tap(find.byIcon(Icons.add));
24 | await tester.pump();
25 |
26 | // Verify that our counter has incremented.
27 | expect(find.text('0'), findsNothing);
28 | expect(find.text('1'), findsOneWidget);
29 | });
30 | }
31 |
--------------------------------------------------------------------------------
/lib/screens/material_main_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutterdesktopapp/utils/app_data.dart';
3 | import 'package:flutterdesktopapp/utils/graphs_provider.dart';
4 | import 'package:flutterdesktopapp/utils/utilities_provider.dart';
5 | import 'package:provider/provider.dart';
6 | import 'package:window_size/window_size.dart';
7 |
8 | import 'home_page.dart';
9 |
10 | class MyApp extends StatelessWidget {
11 | const MyApp({Key key}) : super(key: key);
12 |
13 | @override
14 | Widget build(BuildContext context) {
15 | setWindowTitle("Interpreter Visualizer");
16 |
17 | return MultiProvider(
18 | providers: [
19 | ChangeNotifierProvider(create: (_) => AppData()),
20 | ChangeNotifierProvider(
21 | create: (_) => UtilitiesProvider()),
22 | ChangeNotifierProvider(create: (_) => GraphProvider()),
23 | ],
24 | builder: (context, child) {
25 | return MaterialApp(
26 | title: 'Interpreter Visualizer',
27 | //theme: ,
28 | debugShowCheckedModeBanner: false,
29 | home: HomePage(),
30 | );
31 | });
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/lib/components/resusable_circle.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutterdesktopapp/utils/app_data.dart';
3 | import 'package:flutterdesktopapp/utils/constants.dart';
4 | import 'package:provider/provider.dart';
5 |
6 | class ReusableCircle extends StatelessWidget {
7 | final Function function;
8 | final String headline, title;
9 |
10 | ReusableCircle({this.headline, this.title, this.function});
11 |
12 | @override
13 | Widget build(BuildContext context) {
14 | final isVisualizedProvider = Provider.of(context).isVisualized;
15 | return InkWell(
16 | onTap: isVisualizedProvider ? function : null,
17 | child: CircleAvatar(
18 | backgroundColor:
19 | (isVisualizedProvider ? Colors.indigo : Colors.blueGrey),
20 | radius: 150.0,
21 | child: Column(
22 | crossAxisAlignment: CrossAxisAlignment.center,
23 | mainAxisAlignment: MainAxisAlignment.center,
24 | children: [
25 | Text("$headline", style: text_style_circle),
26 | SizedBox(
27 | height: 20,
28 | ),
29 | Text("$title", style: text_style_circle),
30 | ],
31 | ),
32 | ),
33 | );
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/lib/utils/utilities_provider.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/cupertino.dart';
2 | import 'package:flutter/material.dart';
3 |
4 | class UtilitiesProvider with ChangeNotifier {
5 | List _consoleMessages = [];
6 |
7 | List get consoleMessages => _consoleMessages;
8 |
9 | set consoleMessages(List value) {
10 | _consoleMessages = value;
11 | notifyListeners();
12 | }
13 |
14 | void clearConsoleMessages() {
15 | consoleMessages = [];
16 | }
17 |
18 | void addConsoleMessage(String message, int type) {
19 | // 0 for errors, 1 otherwise
20 | _consoleMessages.add([message, type]);
21 | var temp = List.from(consoleMessages);
22 | consoleMessages = temp;
23 | }
24 |
25 | void addConsoleMessageList(List messages) {
26 | // 0 for errors, 1 otherwise
27 | if (messages == null) return;
28 | for (var m in messages) {
29 | _consoleMessages.add([m[0], m[1]]);
30 | }
31 |
32 | var temp = List.from(consoleMessages);
33 | consoleMessages = temp;
34 | }
35 |
36 | List _richTextList = [];
37 |
38 | List get richTextList => _richTextList;
39 |
40 | set richTextList(List value) {
41 | _richTextList = value;
42 | notifyListeners();
43 | }
44 |
45 | void resetRichTextListColors() {
46 | var len = _richTextList.length;
47 | for (int i = 0; i < len; i++) _richTextList[i][1] = Colors.black;
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/lib/utils/constants.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | final ButtonStyle run_button_style =
4 | ElevatedButton.styleFrom(minimumSize: Size(300, 70));
5 |
6 | var text_style_header_button =
7 | TextStyle(color: Colors.white, fontWeight: FontWeight.bold, fontSize: 20);
8 |
9 | var text_style_phase_title =
10 | TextStyle(color: Colors.black, fontWeight: FontWeight.bold, fontSize: 20);
11 |
12 | var text_style_table = TextStyle(fontWeight: FontWeight.bold, fontSize: 20.0);
13 |
14 | var text_style_console_normal =
15 | TextStyle(fontWeight: FontWeight.bold, fontSize: 18.0);
16 |
17 | var text_style_console_error =
18 | TextStyle(fontWeight: FontWeight.bold, color: Colors.red, fontSize: 18.0);
19 |
20 | var text_style_highlight = TextStyle(
21 | fontWeight: FontWeight.bold,
22 | fontSize: 20.0,
23 | backgroundColor: Colors.yellow,
24 | );
25 |
26 | var text_style_circle =
27 | TextStyle(fontWeight: FontWeight.bold, fontSize: 18.0, color: Colors.white);
28 |
29 | var text_style_graph_title =
30 | TextStyle(fontWeight: FontWeight.bold, fontSize: 12.0, color: Colors.white);
31 |
32 | var text_style_graph_text =
33 | TextStyle(fontWeight: FontWeight.bold, fontSize: 10.0, color: Colors.white);
34 |
35 | var text_style_table_row = TextStyle(
36 | fontWeight: FontWeight.bold,
37 | fontSize: 14.0,
38 | color: Colors.black,
39 | );
40 |
--------------------------------------------------------------------------------
/InterpreterVisualizer/src/main/java/simpleinterpreter/Environment.java:
--------------------------------------------------------------------------------
1 | package simpleinterpreter;
2 |
3 | import java.util.HashMap;
4 | import java.util.Map;
5 |
6 | class Environment {
7 | final Environment enclosing;
8 | private final Map values = new HashMap<>();
9 |
10 | Environment() {
11 | enclosing = null;
12 | }
13 |
14 | Environment(Environment enclosing) {
15 | this.enclosing = enclosing;
16 | }
17 |
18 | void define(String name, Object value) {
19 | values.put(name, value);
20 | }
21 |
22 | Object get(Token name) {
23 | if (values.containsKey(name.lexeme)) {
24 | return values.get(name.lexeme);
25 | }
26 |
27 | if (enclosing != null) return enclosing.get(name);
28 |
29 | throw new RuntimeError(name,
30 | "Undefined variable '" + name.lexeme + "'.");
31 | }
32 |
33 | void assign(Token name, Object value) {
34 | if (values.containsKey(name.lexeme)) {
35 | values.put(name.lexeme, value);
36 | return;
37 | }
38 |
39 | if (enclosing != null) {
40 | enclosing.assign(name, value);
41 | return;
42 | }
43 |
44 | throw new RuntimeError(name, "Undefined variable '" + name.lexeme + "'.");
45 | }
46 |
47 | public Map getValues() {
48 | return values;
49 | }
50 | }
--------------------------------------------------------------------------------
/LoxGrammar:
--------------------------------------------------------------------------------
1 | Here is the grammar of the language which shows its simplicity in the following list of productions flavoured with regular expressions:
2 |
3 | program → declaration* EOF
4 |
5 | declaration → varDecl
6 | | statement;
7 |
8 | varDecl → "var" IDENTIFIER ( "=" expression )? ";"
9 |
10 | statement → exprStmt
11 | | ifStmt
12 | | printStmt
13 | | whileStmt
14 | | block
15 |
16 | exprStmt → expression";"
17 |
18 | ifStmt → "if" "(" expression ")" statement
19 | ( "else" statement )?
20 |
21 | printStmt → "print" expression ";"
22 |
23 | whileStmt → "while" "(" expression ")" statement
24 |
25 | block → "{" declaration* "}"
26 |
27 | expression → assignment
28 |
29 | assignment → IDENTIFIER "=" assignment
30 | | logic_or
31 |
32 | logic_or → logic_and ( "or" logic_and )*
33 |
34 | logic_and → equality ( "and" equality )*
35 |
36 | equality → comparison ( ( "!=" | "==" ) comparison )*
37 |
38 | comparison → term ( ( ">" | ">=" | "<" | "<=" ) term )*
39 |
40 | term → factor ( ( "-" | "+" ) factor )*
41 |
42 | factor → factor ( "/" | "*" ) unary
43 | | unary
44 |
45 |
46 | unary → ( "!" | "-" ) unary
47 | | primary
48 |
49 | primary → "true" | "false" | "nil"
50 | | NUMBER | STRING
51 | | "(" expression ")"
52 | | IDENTIFIER
53 |
54 |
--------------------------------------------------------------------------------
/lib/ui_elements/symbo_table_item.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutterdesktopapp/utils/constants.dart';
3 |
4 | import 'colored_card_box.dart';
5 |
6 | class SymbolTableItem extends StatefulWidget {
7 | final String scope;
8 | final String variable;
9 | final String value;
10 |
11 | SymbolTableItem(this.scope, this.variable, this.value);
12 |
13 | @override
14 | _SymbolTableItemState createState() => _SymbolTableItemState();
15 | }
16 |
17 | class _SymbolTableItemState extends State {
18 | // @override
19 | void dispose() {
20 | print("Symbol Table Item Disposed");
21 | // // TODO: implement dispose
22 | super.dispose();
23 | }
24 |
25 | @override
26 | Widget build(BuildContext context) {
27 | return ColoredCardBox(
28 | color: Colors.lightGreenAccent[200],
29 | child: Row(
30 | mainAxisAlignment: MainAxisAlignment.spaceAround,
31 | children: [
32 | SizedBox(
33 | child: Container(
34 | child: Text("${widget.variable}", style: text_style_table_row)),
35 | width: 125.0,
36 | ),
37 | SizedBox(
38 | child: Container(
39 | child: Text("${widget.value}", style: text_style_table_row)),
40 | width: 80.0,
41 | ),
42 | SizedBox(
43 | child: Container(
44 | child: Text("${widget.scope}", style: text_style_table_row)),
45 | width: 80.0,
46 | ),
47 | ],
48 | ),
49 | );
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/lib/models/response.dart:
--------------------------------------------------------------------------------
1 | import 'dart:convert';
2 |
3 | import 'package:flutterdesktopapp/models/statement.dart';
4 | import 'package:flutterdesktopapp/models/tokens.dart';
5 |
6 | import 'Ast.dart';
7 |
8 | class ResponseParser {
9 | List listOfTokens(String responseBody) {
10 | Map jsonList = json.decode(responseBody);
11 | int len = (jsonList["Tokens"] as List).length;
12 | List listOfTokens = [];
13 | for (int tokenIndex = 0; tokenIndex < len; tokenIndex++) {
14 | listOfTokens.add(Token.fromJson(tokenIndex, jsonList));
15 | }
16 | return listOfTokens;
17 | }
18 |
19 | List listOfParsedStatements(String responseBody) {
20 | Map jsonList = json.decode(responseBody);
21 |
22 | int len = (jsonList["Statements"] as List).length;
23 |
24 | List statements = [];
25 | for (int statementIndex = 0; statementIndex < len; statementIndex++) {
26 | statements
27 | .add(Statement.fromJson(jsonList["Statements"][statementIndex]));
28 | }
29 |
30 | return statements;
31 | }
32 |
33 | List listOfASTs(String responseBody) {
34 | Map jsonList = json.decode(responseBody);
35 |
36 | int len = 0;
37 | try {
38 | len = (jsonList["Statements"] as List).length;
39 | } catch (e) {}
40 |
41 | List statements = [];
42 | for (int statementIndex = 0; statementIndex < len; statementIndex++) {
43 | statements.add(Ast.fromJson(jsonList["Statements"][statementIndex]));
44 | }
45 |
46 | return statements;
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/lib/ui_elements/code_text.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 | import 'package:flutterdesktopapp/ui_elements/text_highlighter.dart';
4 | import 'package:flutterdesktopapp/utils/app_data.dart';
5 | import 'package:provider/provider.dart';
6 |
7 | class CodeText extends StatefulWidget {
8 | CodeText({Key key}) : super(key: key);
9 |
10 | @override
11 | _CodeTextState createState() => _CodeTextState();
12 | }
13 |
14 | class _CodeTextState extends State {
15 | void refresh() {
16 | setState(() {});
17 | }
18 |
19 | @override
20 | Widget build(BuildContext context) {
21 | final appData = Provider.of(context, listen: true);
22 |
23 | var atLeastOneCircle = appData.atLeastOneCircle();
24 |
25 | return SingleChildScrollView(
26 | child: SizedBox(
27 | height: 800,
28 | width: 1200,
29 | child: (atLeastOneCircle)
30 | ? TextHighlighter()
31 | : TextField(
32 | onChanged: (text) {
33 | appData.isVisualizationReady = true;
34 | },
35 | controller: appData.editingController,
36 | autofocus: true,
37 | style: TextStyle(fontSize: 30, fontWeight: FontWeight.bold),
38 | decoration: InputDecoration(
39 | hintText: "Write some code here and visualize!",
40 | ),
41 | keyboardType: TextInputType.multiline,
42 | expands: true,
43 | maxLines: null,
44 | ),
45 | ),
46 | );
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/lib/ui_elements/modes_circles.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutterdesktopapp/components/resusable_circle.dart';
3 |
4 | class ThreeCircles extends StatelessWidget {
5 | final String headline1, title1, headline2, title2, headline3, title3;
6 | final Function function1;
7 | final Function function2;
8 | final Function function3;
9 |
10 | ThreeCircles(
11 | {this.headline1,
12 | this.title1,
13 | this.function1,
14 | this.headline2,
15 | this.title2,
16 | this.function2,
17 | this.headline3,
18 | this.title3,
19 | this.function3});
20 |
21 | @override
22 | Widget build(BuildContext context) {
23 | return Expanded(
24 | child: Column(
25 | children: [
26 | Expanded(
27 | child: Row(
28 | mainAxisAlignment: MainAxisAlignment.center,
29 | children: [
30 | Expanded(
31 | child: ReusableCircle(
32 | headline: headline1,
33 | title: title1,
34 | function: function1,
35 | )),
36 | SizedBox(
37 | width: 30,
38 | ),
39 | Expanded(
40 | child: ReusableCircle(
41 | headline: headline2,
42 | title: title2,
43 | function: function2,
44 | ))
45 | ],
46 | ),
47 | ),
48 | Expanded(
49 | child: ReusableCircle(
50 | headline: headline3, title: title3, function: function3)),
51 | ],
52 | ),
53 | );
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/ios/Runner/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/ios/Runner/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | flutterdesktopapp
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | $(FLUTTER_BUILD_NAME)
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | $(FLUTTER_BUILD_NUMBER)
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UISupportedInterfaceOrientations
30 |
31 | UIInterfaceOrientationPortrait
32 | UIInterfaceOrientationLandscapeLeft
33 | UIInterfaceOrientationLandscapeRight
34 |
35 | UISupportedInterfaceOrientations~ipad
36 |
37 | UIInterfaceOrientationPortrait
38 | UIInterfaceOrientationPortraitUpsideDown
39 | UIInterfaceOrientationLandscapeLeft
40 | UIInterfaceOrientationLandscapeRight
41 |
42 | UIViewControllerBasedStatusBarAppearance
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/lib/screens/select_visualization_mode.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutterdesktopapp/screens/first_page.dart';
3 | import 'package:flutterdesktopapp/screens/semantic_page.dart';
4 | import 'package:flutterdesktopapp/screens/syntactic_and_statement_page.dart';
5 | import 'package:flutterdesktopapp/screens/tokens_page.dart';
6 | import 'package:flutterdesktopapp/utils/app_data.dart';
7 | import 'package:provider/provider.dart';
8 |
9 | class Modes extends StatefulWidget {
10 | Modes({Key key}) : super(key: key);
11 |
12 | @override
13 | _ModesState createState() => _ModesState();
14 | }
15 |
16 | class _ModesState extends State {
17 | @override
18 | Widget build(BuildContext context) {
19 | final appData = Provider.of(context);
20 |
21 | Widget getClickedPage() {
22 | if (appData.isVisualized && appData.circleOneClicked) {
23 | return TokensPage(appData.tokensList.length);
24 | } else if (appData.isVisualized && appData.circleTwoClicked) {
25 | return SyntacticPage(
26 | appData.parsedStatementsList[appData.visualizedStatementIndex]
27 | .graphs.length,
28 | appData.visualizedStatementIndex);
29 | } else if (appData.isVisualized && appData.circleThreeClicked) {
30 | return SemanticPage(
31 | appData
32 | .astsList[appData.visualizedStatementIndex].visitedNode.length,
33 | appData.visualizedStatementIndex);
34 | }
35 |
36 | return PageOne();
37 | }
38 |
39 | return Builder(
40 | builder: (context) {
41 | return Container(
42 | child: getClickedPage(),
43 | );
44 | },
45 | );
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/lib/ui_elements/console_panel.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutterdesktopapp/utils/constants.dart';
3 | import 'package:flutterdesktopapp/utils/utilities_provider.dart';
4 | import 'package:provider/provider.dart';
5 |
6 | class ConsolePanel extends StatefulWidget {
7 | const ConsolePanel({Key key}) : super(key: key);
8 |
9 | @override
10 | _ConsolePanelState createState() => _ConsolePanelState();
11 | }
12 |
13 | class _ConsolePanelState extends State {
14 | @override
15 | Widget build(BuildContext context) {
16 | final appData = Provider.of(context);
17 | var consoleMessages = appData.consoleMessages;
18 | return SizedBox(
19 | width: 1200,
20 | child: Padding(
21 | padding: const EdgeInsets.all(8.0),
22 | child: (consoleMessages.isEmpty
23 | ? null
24 | : ListView.builder(
25 | itemCount: consoleMessages.length,
26 | itemBuilder: (context, index) {
27 | return Padding(
28 | padding: const EdgeInsets.all(6.0),
29 | child: Text(
30 | "-> " +
31 | consoleMessages[
32 | consoleMessages.length - index - 1][0],
33 | style: (consoleMessages[consoleMessages.length -
34 | index -
35 | 1][1] ==
36 | 0
37 | ? text_style_console_error
38 | : text_style_console_normal)),
39 | );
40 | }))));
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/InterpreterVisualizer/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | org.springframework.boot
7 | spring-boot-starter-parent
8 | 2.5.2
9 |
10 |
11 | com.example
12 | InterpreterVisualizer
13 | 0.0.1-SNAPSHOT
14 | InterpreterVisualizer
15 | Demo project for Spring Boot
16 |
17 | 11
18 |
19 |
20 |
21 | org.springframework.boot
22 | spring-boot-starter-web
23 |
24 |
25 |
26 | org.springframework.boot
27 | spring-boot-starter-test
28 | test
29 |
30 |
31 | org.json
32 | json
33 | 20210307
34 |
35 |
36 |
37 |
38 |
39 | org.springframework.boot
40 | spring-boot-maven-plugin
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/InterpreterVisualizer/src/main/java/simpleinterpreter/InterpreterAdapter.java:
--------------------------------------------------------------------------------
1 | package simpleinterpreter;
2 |
3 | import org.json.JSONObject;
4 |
5 | import java.util.HashMap;
6 | import java.util.Map;
7 |
8 | public class InterpreterAdapter {
9 |
10 | private static final JSONObject invalidTokenError = new JSONObject().put("ERROR", "Invalid Token.");
11 | private static final InterpreterAdapter interpreterAdapter = new InterpreterAdapter();
12 | private static final Map interpreters = new HashMap<>();
13 |
14 |
15 | private InterpreterAdapter() {
16 | }
17 |
18 | public static InterpreterAdapter getInterpreterAdapter() {
19 | return interpreterAdapter;
20 | }
21 |
22 |
23 | public void startInterpreter(String token, String source) {
24 | interpreters.put(token, new SimpleInterpreter(source));
25 | }
26 |
27 | public JSONObject getLexicalAnalysis(String token) {
28 | if (interpreters.get(token) == null) {
29 | return invalidTokenError;
30 | }
31 | SimpleInterpreter interpreter = interpreters.get(token);
32 | return interpreter.getLexicalAnalysis();
33 | }
34 |
35 | public JSONObject getSyntacticAnalysis(String token) {
36 | if (interpreters.get(token) == null) {
37 | return invalidTokenError;
38 | }
39 | SimpleInterpreter interpreter = interpreters.get(token);
40 | return interpreter.getSyntacticAnalysis();
41 | }
42 |
43 | public JSONObject getSemanticAnalysis(String token) {
44 | if (interpreters.get(token) == null) {
45 | return invalidTokenError;
46 | }
47 | SimpleInterpreter interpreter = interpreters.get(token);
48 | return interpreter.getSemanticAnalysis();
49 | }
50 |
51 | }
52 |
--------------------------------------------------------------------------------
/lib/models/Ast.dart:
--------------------------------------------------------------------------------
1 | class Ast {
2 | String _astGraph;
3 | List _visitedNode;
4 | List _nodesData;
5 | List _symbolTableIndexSync;
6 | List _symbolTable;
7 | Map _errors;
8 | Map _outputMessages;
9 |
10 | Ast(
11 | this._astGraph,
12 | this._visitedNode,
13 | this._nodesData,
14 | this._symbolTableIndexSync,
15 | this._symbolTable,
16 | this._errors,
17 | this._outputMessages);
18 |
19 | factory Ast.fromJson(Map json) {
20 | String ast = json["AST"].toString();
21 |
22 | List visitedNode = (json["Visited Nodes"] as List);
23 |
24 | List nodesData = (json["Nodes"] as List);
25 |
26 | List symbolTableIndexSync =
27 | (json["Symbol Table Index Sync"] as List);
28 |
29 | Map errorsString =
30 | (json["Errors"] as Map);
31 |
32 | Map errors = {};
33 | for (String s in errorsString.keys) {
34 | errors[int.parse(s)] = errorsString[s].toString();
35 | }
36 |
37 | Map outputMessagesString =
38 | (json["Output Messages"] as Map);
39 | Map outputMessages = {};
40 | for (String s in outputMessagesString.keys) {
41 | outputMessages[int.parse(s)] = outputMessagesString[s].toString();
42 | }
43 |
44 | List symbolTable = (json["Symbol Table"] as List);
45 |
46 | return Ast(ast, visitedNode, nodesData, symbolTableIndexSync, symbolTable,
47 | errors, outputMessages);
48 | }
49 |
50 | Map get outputMessages => _outputMessages;
51 |
52 | Map get errors => _errors;
53 |
54 | List get symbolTable => _symbolTable;
55 |
56 | List get symbolTableIndexSync => _symbolTableIndexSync;
57 |
58 | List get nodesData => _nodesData;
59 |
60 | List get visitedNode => _visitedNode;
61 |
62 | String get astGraph => _astGraph;
63 | }
64 |
--------------------------------------------------------------------------------
/lib/models/tokens.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class Token {
4 | String _tokenType;
5 | String _lexeme;
6 | String _literal;
7 | int _line;
8 | int _start;
9 | int _end;
10 | Color _color;
11 | List _errors;
12 |
13 | List get errors => _errors;
14 |
15 | Color get color => _color;
16 |
17 | Token(this._tokenType, this._lexeme, this._literal, this._line, this._start,
18 | this._end, int category, this._errors) {
19 | this._color = getTokenColor(category);
20 | }
21 |
22 | factory Token.fromJson(int tokenIndex, Map json) {
23 | List errors = [];
24 | if (json["Errors"][tokenIndex.toString()] != null) {
25 | int length =
26 | (json["Errors"][tokenIndex.toString()] as List).length;
27 | for (int i = 0; i < length; i++) {
28 | errors.add(json["Errors"][tokenIndex.toString()][i].toString());
29 | }
30 | }
31 | return Token(
32 | json["Tokens"][tokenIndex]['type'],
33 | json["Tokens"][tokenIndex]['lexeme'],
34 | json["Tokens"][tokenIndex]['literal'],
35 | json["Tokens"][tokenIndex]['line'],
36 | json["Tokens"][tokenIndex]['start'],
37 | json["Tokens"][tokenIndex]['end'],
38 | json["Tokens"][tokenIndex]['category'],
39 | errors,
40 | );
41 | }
42 |
43 | String get tokenType => _tokenType;
44 |
45 | String get lexeme => _lexeme;
46 |
47 | int get line => _line;
48 |
49 | String get literal => _literal;
50 |
51 | int get end => _end;
52 |
53 | int get start => _start;
54 |
55 | Color getTokenColor(var tokenType) {
56 | switch (tokenType) {
57 | case 1:
58 | return Colors.teal;
59 | break;
60 | case 2:
61 | return Colors.greenAccent;
62 | break;
63 | case 3:
64 | return Colors.amberAccent;
65 | break;
66 | case 4:
67 | return Colors.blueAccent;
68 | break;
69 | default:
70 | return Colors.grey;
71 | }
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/InterpreterVisualizer/src/main/java/api/interpretervisualizer/controller/WebController.java:
--------------------------------------------------------------------------------
1 | package api.interpretervisualizer.controller;
2 |
3 | import org.springframework.web.bind.annotation.*;
4 | import simpleinterpreter.InterpreterAdapter;
5 |
6 | import java.security.SecureRandom;
7 | import java.util.Base64;
8 |
9 | @CrossOrigin(origins = "*", allowedHeaders = "*")
10 | @RestController
11 | public class WebController {
12 |
13 | private static final SecureRandom secureRandom = new SecureRandom(); //threadsafe
14 | private static final Base64.Encoder base64Encoder = Base64.getUrlEncoder(); //threadsafe
15 | private static final InterpreterAdapter interpreterAdapter = InterpreterAdapter.getInterpreterAdapter();
16 |
17 | String generateToken() {
18 | byte[] randomBytes = new byte[24];
19 | secureRandom.nextBytes(randomBytes);
20 | String token = base64Encoder.encodeToString(randomBytes);
21 | return token;
22 | }
23 |
24 | @RequestMapping("/interpreter/lexical")
25 | public String lexicalAnalysis(@RequestParam(value = "token") String token) {
26 | System.out.println("Lexical Analysis Requested!");
27 | return interpreterAdapter.getLexicalAnalysis(token).toString();
28 | }
29 |
30 | @RequestMapping("/interpreter/syntactic")
31 | public String syntacticAnalysis(@RequestParam(value = "token") String token) {
32 | System.out.println("Syntactic Analysis Requested!");
33 | return interpreterAdapter.getSyntacticAnalysis(token).toString();
34 | }
35 |
36 | @RequestMapping("/interpreter/semantic")
37 | public String semanticAnalysis(@RequestParam(value = "token") String token) {
38 | System.out.println("Semantic Analysis Requested!");
39 | return interpreterAdapter.getSemanticAnalysis(token).toString();
40 | }
41 |
42 | @RequestMapping(value = "/interpreter/sourcecode", method = RequestMethod.POST)
43 | public String sourceCode(@RequestBody String source) {
44 | String generatedtoken = generateToken();
45 | interpreterAdapter.startInterpreter(generatedtoken, source);
46 | return "{\"Token\":\"" + generatedtoken + "\"}";
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/InterpreterVisualizer/src/main/java/simpleinterpreter/Token.java:
--------------------------------------------------------------------------------
1 | package simpleinterpreter;
2 |
3 | import org.json.JSONObject;
4 |
5 | import java.util.Arrays;
6 |
7 | import static simpleinterpreter.TokenType.*;
8 |
9 | class Token {
10 | final TokenType type;
11 | final String lexeme;
12 | final Object literal;
13 | final int line;
14 | final int start;
15 | final int end;
16 |
17 | Token(TokenType type, String lexeme, Object literal, int line, int start, int end) {
18 | this.type = type;
19 | this.lexeme = lexeme;
20 | this.literal = literal;
21 | this.line = line;
22 | this.start = start;
23 | this.end = end;
24 | }
25 |
26 | int getTokenCategory() {
27 | TokenType[] single_char = {LEFT_PAREN, RIGHT_PAREN, LEFT_BRACE, RIGHT_BRACE, COMMA, DOT, MINUS, PLUS, SEMICOLON, SLASH, STAR};
28 |
29 | TokenType[] two_chars = {BANG, BANG_EQUAL, EQUAL, EQUAL_EQUAL, GREATER, GREATER_EQUAL, LESS, LESS_EQUAL};
30 |
31 | TokenType[] literals = {IDENTIFIER, STRING, NUMBER};
32 |
33 | TokenType[] keywords = {AND, CLASS, ELSE, FALSE, FUN, FOR, IF, NIL, OR, PRINT, RETURN, SUPER, THIS, TRUE, VAR, WHILE};
34 |
35 | if (Arrays.asList(single_char).contains(type)) {
36 | return 1;
37 | } else if (Arrays.asList(two_chars).contains(type)) {
38 | return 2;
39 | } else if (Arrays.asList(literals).contains(type)) {
40 | return 3;
41 | } else if (Arrays.asList(keywords).contains(type)) {
42 | return 4;
43 | }
44 | return 0;
45 | }
46 |
47 | public String toString() {
48 | return type + "," + lexeme + "," + literal + "," + line + "," + start + "," + end + "," + getTokenCategory();
49 | }
50 |
51 | JSONObject getTokenJSON() {
52 | JSONObject tokenJSON = new JSONObject();
53 | tokenJSON.put("type", type);
54 | tokenJSON.put("lexeme", lexeme);
55 | tokenJSON.put("literal", (literal == null ? "" : literal.toString()));
56 | tokenJSON.put("line", line);
57 | tokenJSON.put("line", line);
58 | tokenJSON.put("start", start);
59 | tokenJSON.put("end", end);
60 | tokenJSON.put("category", getTokenCategory());
61 | return tokenJSON;
62 | }
63 | }
--------------------------------------------------------------------------------
/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
13 |
17 |
21 |
26 |
30 |
31 |
32 |
33 |
34 |
35 |
37 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/contribution.md:
--------------------------------------------------------------------------------
1 | # Contribution Guidelines
2 | We are very grateful for your contribution and your time you spend to help us enhance the application and we are excited to welcome you.
3 | Make sure to understand the file structure before any edit.
4 |
5 | If you're new to open source, read [this article](https://en.wikipedia.org/wiki/Open_source) to get involved.
6 |
7 | # Here are the ways you can help
8 | 1. Improve existing features.
9 | 2. Add a new feature.
10 | 3. Test for issues and report them.
11 | 4. Help in code reviewing and provide feedback.
12 |
13 | # Required Steps to follow to make your PR accepted and merged
14 | 1. Take care about Encapsulation rules.
15 | 2. The names of functions, variables, components and classes should be descriptive
16 | and be according to the Dart [Naming Conventions](https://dart.dev/guides/language/effective-dart/style) and the Java [Naming Conventions](https://www.javatpoint.com/java-naming-conventions).
17 | 3. No unnecessary comments.
18 | 4. No warnings on the console or the terminal (always lint your code).
19 |
20 | # Add a new module or component
21 | If you see that there's a new module suitable for the application, write a proposal first that describes the following:
22 | 1. What the module is ? and what does it do ?
23 | 2. Why you think it's required ?
24 | 3. What are the requirements you want to finish this module ?
25 | 4. What is the time expected to finish it ?
26 | 5. What are the tools you will use to build it ?
27 | 6. What are the components and services you'll add ? (specify the name of the component and the function of this component).
28 |
29 | After your proposal is accepted you can start adding the new module or the component that you wish,
30 | but make sure that you adhere to the project structure and if any dependency is added, also,
31 | make sure that you add it in the readme.md file.
32 |
33 | # Found a critical bug
34 | If you found a critical bug, open an issue on the issues tab and provide a detailed description about what you found.
35 |
36 | # Frequently Asked Questions
37 | **I found a typo, should I report an issue before I can make a pull request?**
38 |
39 | For typos and other wording changes, you can directly open pull requests without first creating an issue.
40 | Issues are more for discussing larger problems associated with code or structural aspects of the curriculum.
41 |
--------------------------------------------------------------------------------
/ios/Runner/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/lib/screens/tokens_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/cupertino.dart';
2 | import 'package:flutter/material.dart';
3 | import 'package:flutterdesktopapp/ui_elements/card_box.dart';
4 | import 'package:flutterdesktopapp/ui_elements/token_item.dart';
5 | import 'package:flutterdesktopapp/utils/constants.dart';
6 |
7 | class TokensPage extends StatefulWidget {
8 | final int numberOfTokens;
9 |
10 | TokensPage(this.numberOfTokens);
11 |
12 | @override
13 | _TokensPageState createState() => _TokensPageState();
14 | }
15 |
16 | class _TokensPageState extends State with TickerProviderStateMixin {
17 | AnimationController _animationController;
18 | double animationDuration;
19 | int durationOfSingleToken;
20 | int totalDuration;
21 |
22 | @override
23 | void initState() {
24 | // TODO: implement initState
25 | super.initState();
26 | durationOfSingleToken = 1500;
27 | totalDuration = widget.numberOfTokens * durationOfSingleToken;
28 | _animationController = AnimationController(
29 | vsync: this, duration: new Duration(milliseconds: totalDuration));
30 |
31 | animationDuration = durationOfSingleToken / totalDuration;
32 | _animationController.forward();
33 | }
34 |
35 | @override
36 | void dispose() {
37 | print("Tokens Page Disposed");
38 | _animationController.dispose();
39 | super.dispose();
40 | }
41 |
42 | @override
43 | Widget build(BuildContext context) {
44 | return Container(
45 | child: Column(
46 | mainAxisAlignment: MainAxisAlignment.center,
47 | children: [
48 | CardBox(
49 | child: SizedBox(
50 | height: 30,
51 | child: Row(
52 | mainAxisAlignment: MainAxisAlignment.spaceBetween,
53 | children: [
54 | Text(
55 | "Token Type",
56 | style: text_style_table,
57 | ),
58 | Text(
59 | "Lexeme",
60 | style: text_style_table,
61 | ),
62 | Text(
63 | "Literal",
64 | style: text_style_table,
65 | ),
66 | Text(
67 | "Line No.",
68 | style: text_style_table,
69 | )
70 | ],
71 | ),
72 | ),
73 | ),
74 | Expanded(
75 | child: ListView.builder(
76 | itemCount: widget.numberOfTokens,
77 | itemBuilder: (context, index) {
78 | return TokenItem(
79 | index, animationDuration, _animationController);
80 | },
81 | ),
82 | )
83 | ],
84 | ),
85 | );
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/lib/services/networking.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 | import 'dart:convert';
3 |
4 | import 'package:flutterdesktopapp/models/Ast.dart';
5 | import 'package:flutterdesktopapp/models/response.dart';
6 | import 'package:flutterdesktopapp/models/statement.dart';
7 | import 'package:flutterdesktopapp/models/tokens.dart';
8 | import 'package:http/http.dart' as http;
9 |
10 | class NetworkHelper {
11 | factory NetworkHelper() {
12 | return internalObject;
13 | }
14 |
15 | static const String ip_address = "http://192.168.1.5";
16 | static const String port = "9090";
17 | static const String url_sendCode = "/interpreter/sourcecode/";
18 | static const String url_getLexical = "/interpreter/lexical?token=";
19 | static const String url_getSyntactic = "/interpreter/syntactic?token=";
20 | static const String url_getSemantic = "/interpreter/semantic?token=";
21 |
22 | static final NetworkHelper internalObject = NetworkHelper._internal();
23 |
24 | static var token;
25 |
26 | NetworkHelper._internal();
27 |
28 | ResponseParser responseParser = ResponseParser();
29 |
30 | Future sendCodeToInterpreter(String code) async {
31 | List consoleMessages = [];
32 |
33 | final response = await http.post(
34 | Uri.parse('$ip_address:$port$url_sendCode'),
35 | headers: {
36 | 'Content-Type': 'application/json',
37 | 'Access-Control-Allow-Origin': '*'
38 | },
39 | body: code,
40 | );
41 |
42 | if (response.statusCode == 200) {
43 | consoleMessages.add(["Connection Established!", 1]);
44 | consoleMessages.add(["Authentication Token Received Successfully!", 1]);
45 | token = json.decode(response.body)["Token"];
46 | } else {
47 | consoleMessages.add(["Failed to send the code.", 0]);
48 | }
49 |
50 | return consoleMessages;
51 | }
52 |
53 | Future> getLexicalAnalysis() async {
54 | final response =
55 | await http.get(Uri.parse('$ip_address:$port$url_getLexical$token'));
56 | if (response.statusCode == 200) {
57 | print("Requesting Lexical Analysis Completed Successfully!");
58 | // print(responseParser.listOfTokens(response.body));
59 | return responseParser.listOfTokens(response.body);
60 | } else {}
61 | }
62 |
63 | Future> getSyntacticAnalysis() async {
64 | final response =
65 | await http.get(Uri.parse('$ip_address:$port$url_getSyntactic$token'));
66 | if (response.statusCode == 200) {
67 | return responseParser.listOfParsedStatements(response.body);
68 | } else {}
69 | }
70 |
71 | Future> getSemanticAnalysis() async {
72 | final response =
73 | await http.get(Uri.parse('$ip_address:$port$url_getSemantic$token'));
74 | if (response.statusCode == 200) {
75 | return responseParser.listOfASTs(response.body);
76 | } else {}
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/lib/ui_elements/symbol_table.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/cupertino.dart';
2 | import 'package:flutter/material.dart';
3 | import 'package:flutterdesktopapp/ui_elements/card_box.dart';
4 | import 'package:flutterdesktopapp/ui_elements/symbo_table_item.dart';
5 | import 'package:flutterdesktopapp/utils/app_data.dart';
6 | import 'package:flutterdesktopapp/utils/constants.dart';
7 | import 'package:flutterdesktopapp/utils/graphs_provider.dart';
8 | import 'package:provider/provider.dart';
9 |
10 | class SymbolTable extends StatefulWidget {
11 | @override
12 | _SymbolTableState createState() => _SymbolTableState();
13 | }
14 |
15 | class _SymbolTableState extends State
16 | with TickerProviderStateMixin {
17 | @override
18 | void dispose() {
19 | print("Symbol Table Page Disposed");
20 | super.dispose();
21 | }
22 |
23 | @override
24 | Widget build(BuildContext context) {
25 | var appData = Provider.of(context);
26 | final graphProvider = Provider.of(context);
27 |
28 | var symbolTable =
29 | appData.astsList[graphProvider.visualizedStatementIndex].symbolTable;
30 | var symbolTableSyncIndex = appData
31 | .astsList[graphProvider.visualizedStatementIndex]
32 | .symbolTableIndexSync[graphProvider.visualizedStepIndex];
33 | var currentSymbolTable = symbolTable[symbolTableSyncIndex];
34 |
35 | List scopes = [], variables = [], values = [];
36 | for (var scope in currentSymbolTable.keys) {
37 | for (var variable in currentSymbolTable[scope].keys) {
38 | scopes.add(scope);
39 | variables.add(variable);
40 | values.add(currentSymbolTable[scope][variable]);
41 | }
42 | }
43 |
44 | int len = scopes.length;
45 |
46 | return Container(
47 | child: Column(
48 | mainAxisAlignment: MainAxisAlignment.center,
49 | children: [
50 | CardBox(
51 | child: SizedBox(
52 | height: 30,
53 | child: Row(
54 | mainAxisAlignment: MainAxisAlignment.spaceAround,
55 | children: [
56 | Text(
57 | "Variable Name",
58 | style: text_style_table,
59 | ),
60 | Text(
61 | "Value",
62 | style: text_style_table,
63 | ),
64 | Text(
65 | "Scope",
66 | style: text_style_table,
67 | ),
68 | ],
69 | ),
70 | ),
71 | ),
72 | Expanded(
73 | child: ListView.builder(
74 | itemCount: len,
75 | itemBuilder: (context, index) {
76 | return SymbolTableItem(scopes[index].toString(),
77 | variables[index].toString(), values[index].toString());
78 | },
79 | ),
80 | )
81 | ],
82 | ),
83 | );
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/lib/screens/home_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutterdesktopapp/screens/select_visualization_mode.dart';
3 | import 'package:flutterdesktopapp/ui_elements/card_box.dart';
4 | import 'package:flutterdesktopapp/ui_elements/code_text.dart';
5 | import 'package:flutterdesktopapp/ui_elements/console_panel.dart';
6 | import 'package:flutterdesktopapp/ui_elements/control_buttons.dart';
7 | import 'package:flutterdesktopapp/ui_elements/symbol_table.dart';
8 | import 'package:flutterdesktopapp/utils/app_data.dart';
9 | import 'package:provider/provider.dart';
10 |
11 | import 'parsing_ast_page.dart';
12 |
13 | class HomePage extends StatelessWidget {
14 | const HomePage({Key key}) : super(key: key);
15 |
16 | @override
17 | Widget build(BuildContext context) {
18 | final appData = Provider.of(context);
19 |
20 | return Scaffold(
21 | appBar: AppBar(
22 | toolbarHeight: 40,
23 | title: Center(child: Text("Interpreter Visualizer", style: TextStyle(fontWeight: FontWeight.bold),)),
24 | ),
25 | body: Container(
26 | child: Row(
27 | crossAxisAlignment: CrossAxisAlignment.stretch,
28 | mainAxisAlignment: MainAxisAlignment.start,
29 | children: [
30 | Expanded(
31 | flex: 3,
32 | child: Column(
33 | mainAxisAlignment: MainAxisAlignment.start,
34 | crossAxisAlignment: CrossAxisAlignment.start,
35 | children: [
36 | Expanded(
37 | flex: 3,
38 | child: CardBox(
39 | child: CodeText(),
40 | )),
41 | Expanded(flex: 1, child: CardBox(child: ConsolePanel())),
42 | ],
43 | ),
44 | ),
45 | Expanded(
46 | flex: 7,
47 | child: Column(
48 | crossAxisAlignment: CrossAxisAlignment.stretch,
49 | mainAxisAlignment: MainAxisAlignment.start,
50 | children: [
51 | Expanded(flex: 1, child: CardBox(child: ControlButtons())),
52 | Expanded(
53 | flex: 7,
54 | child: Row(
55 | children: [
56 | Expanded(flex: 1, child: CardBox(child: Modes())),
57 | Visibility(
58 | visible: appData.circleTwoClicked,
59 | child: Expanded(
60 | flex: 1,
61 | child: CardBox(child: ParsingASTPage()))),
62 | ],
63 | )),
64 | Visibility(
65 | visible: (appData.circleThreeClicked),
66 | child:
67 | Expanded(flex: 3, child: CardBox(child: SymbolTable())),
68 | ),
69 | ],
70 | ),
71 | ),
72 | ],
73 | ),
74 | ),
75 | );
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/lib/models/statement.dart:
--------------------------------------------------------------------------------
1 | import 'parsing_ast.dart';
2 |
3 | class Statement {
4 | ParsingAst _astGraph;
5 | List _nodesData;
6 | List _graphs;
7 | List _visitedNode;
8 | List _astGraphIndexSync;
9 | Map _consumedTokens;
10 | Map _errors;
11 |
12 | Statement(
13 | this._nodesData,
14 | this._graphs,
15 | this._visitedNode,
16 | this._consumedTokens,
17 | this._errors,
18 | this._astGraphIndexSync,
19 | this._astGraph);
20 |
21 | factory Statement.fromJson(Map json) {
22 | List nodesDataJSON = (json["Nodes"] as List);
23 | List nodesData = [];
24 |
25 | nodesData = nodesDataJSON;
26 |
27 | List graphs = (json["Graphs"] as List);
28 |
29 | List visitedNodes = (json["Visited Nodes"] as List);
30 |
31 | List consumedTokensJSON = (json["Consumed Tokens"] as List);
32 | Map consumedTokens = {};
33 | for (var consumedTokensMap in consumedTokensJSON) {
34 | var key =
35 | int.parse((consumedTokensMap as Map).keys.first);
36 | var listOfTokens =
37 | (consumedTokensMap as Map).values.first;
38 | consumedTokens[key] = listOfTokens;
39 | }
40 |
41 | List errorsJSON = (json["Errors"] as List);
42 | Map errors = {};
43 | for (var errorMap in errorsJSON) {
44 | var key = int.parse((errorMap as Map).keys.first);
45 |
46 | var errorMessage =
47 | (errorMap as Map).values.first.toString();
48 |
49 | if (errors.containsKey(key)) {
50 | errors[key].add(errorMessage);
51 | } else {
52 | errors[key] = [errorMessage];
53 | }
54 | }
55 |
56 | List astGraphIndexSync = (json["AST Graph Index Sync"] as List);
57 |
58 | ParsingAst astGraph = ParsingAst.fromJson(json["AST"]);
59 |
60 | return Statement(nodesData, graphs, visitedNodes, consumedTokens, errors,
61 | astGraphIndexSync, astGraph);
62 | }
63 |
64 | Map get errors => _errors;
65 |
66 | set errors(Map value) {
67 | _errors = value;
68 | }
69 |
70 | Map get consumedTokens => _consumedTokens;
71 |
72 | set consumedTokens(Map value) {
73 | _consumedTokens = value;
74 | }
75 |
76 | List get astGraphIndexSync => _astGraphIndexSync;
77 |
78 | set astGraphIndexSync(List value) {
79 | _astGraphIndexSync = value;
80 | }
81 |
82 | List get visitedNode => _visitedNode;
83 |
84 | set visitedNode(List value) {
85 | _visitedNode = value;
86 | }
87 |
88 | List get graphs => _graphs;
89 |
90 | set graphs(List value) {
91 | _graphs = value;
92 | }
93 |
94 | List get nodesData => _nodesData;
95 |
96 | set nodesData(List value) {
97 | _nodesData = value;
98 | }
99 |
100 | ParsingAst get astGraph => _astGraph;
101 |
102 | set astGraph(ParsingAst value) {
103 | _astGraph = value;
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "20x20",
5 | "idiom" : "iphone",
6 | "filename" : "Icon-App-20x20@2x.png",
7 | "scale" : "2x"
8 | },
9 | {
10 | "size" : "20x20",
11 | "idiom" : "iphone",
12 | "filename" : "Icon-App-20x20@3x.png",
13 | "scale" : "3x"
14 | },
15 | {
16 | "size" : "29x29",
17 | "idiom" : "iphone",
18 | "filename" : "Icon-App-29x29@1x.png",
19 | "scale" : "1x"
20 | },
21 | {
22 | "size" : "29x29",
23 | "idiom" : "iphone",
24 | "filename" : "Icon-App-29x29@2x.png",
25 | "scale" : "2x"
26 | },
27 | {
28 | "size" : "29x29",
29 | "idiom" : "iphone",
30 | "filename" : "Icon-App-29x29@3x.png",
31 | "scale" : "3x"
32 | },
33 | {
34 | "size" : "40x40",
35 | "idiom" : "iphone",
36 | "filename" : "Icon-App-40x40@2x.png",
37 | "scale" : "2x"
38 | },
39 | {
40 | "size" : "40x40",
41 | "idiom" : "iphone",
42 | "filename" : "Icon-App-40x40@3x.png",
43 | "scale" : "3x"
44 | },
45 | {
46 | "size" : "60x60",
47 | "idiom" : "iphone",
48 | "filename" : "Icon-App-60x60@2x.png",
49 | "scale" : "2x"
50 | },
51 | {
52 | "size" : "60x60",
53 | "idiom" : "iphone",
54 | "filename" : "Icon-App-60x60@3x.png",
55 | "scale" : "3x"
56 | },
57 | {
58 | "size" : "20x20",
59 | "idiom" : "ipad",
60 | "filename" : "Icon-App-20x20@1x.png",
61 | "scale" : "1x"
62 | },
63 | {
64 | "size" : "20x20",
65 | "idiom" : "ipad",
66 | "filename" : "Icon-App-20x20@2x.png",
67 | "scale" : "2x"
68 | },
69 | {
70 | "size" : "29x29",
71 | "idiom" : "ipad",
72 | "filename" : "Icon-App-29x29@1x.png",
73 | "scale" : "1x"
74 | },
75 | {
76 | "size" : "29x29",
77 | "idiom" : "ipad",
78 | "filename" : "Icon-App-29x29@2x.png",
79 | "scale" : "2x"
80 | },
81 | {
82 | "size" : "40x40",
83 | "idiom" : "ipad",
84 | "filename" : "Icon-App-40x40@1x.png",
85 | "scale" : "1x"
86 | },
87 | {
88 | "size" : "40x40",
89 | "idiom" : "ipad",
90 | "filename" : "Icon-App-40x40@2x.png",
91 | "scale" : "2x"
92 | },
93 | {
94 | "size" : "76x76",
95 | "idiom" : "ipad",
96 | "filename" : "Icon-App-76x76@1x.png",
97 | "scale" : "1x"
98 | },
99 | {
100 | "size" : "76x76",
101 | "idiom" : "ipad",
102 | "filename" : "Icon-App-76x76@2x.png",
103 | "scale" : "2x"
104 | },
105 | {
106 | "size" : "83.5x83.5",
107 | "idiom" : "ipad",
108 | "filename" : "Icon-App-83.5x83.5@2x.png",
109 | "scale" : "2x"
110 | },
111 | {
112 | "size" : "1024x1024",
113 | "idiom" : "ios-marketing",
114 | "filename" : "Icon-App-1024x1024@1x.png",
115 | "scale" : "1x"
116 | }
117 | ],
118 | "info" : {
119 | "version" : 1,
120 | "author" : "xcode"
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/linux/flutter/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.10)
2 |
3 | set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral")
4 |
5 | # Configuration provided via flutter tool.
6 | include(${EPHEMERAL_DIR}/generated_config.cmake)
7 |
8 | # TODO: Move the rest of this into files in ephemeral. See
9 | # https://github.com/flutter/flutter/issues/57146.
10 |
11 | # Serves the same purpose as list(TRANSFORM ... PREPEND ...),
12 | # which isn't available in 3.10.
13 | function(list_prepend LIST_NAME PREFIX)
14 | set(NEW_LIST "")
15 | foreach(element ${${LIST_NAME}})
16 | list(APPEND NEW_LIST "${PREFIX}${element}")
17 | endforeach(element)
18 | set(${LIST_NAME} "${NEW_LIST}" PARENT_SCOPE)
19 | endfunction()
20 |
21 | # === Flutter Library ===
22 | # System-level dependencies.
23 | find_package(PkgConfig REQUIRED)
24 | pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0)
25 | pkg_check_modules(GLIB REQUIRED IMPORTED_TARGET glib-2.0)
26 | pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0)
27 | pkg_check_modules(BLKID REQUIRED IMPORTED_TARGET blkid)
28 | pkg_check_modules(LZMA REQUIRED IMPORTED_TARGET liblzma)
29 |
30 | set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/libflutter_linux_gtk.so")
31 |
32 | # Published to parent scope for install step.
33 | set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE)
34 | set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE)
35 | set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE)
36 | set(AOT_LIBRARY "${PROJECT_DIR}/build/lib/libapp.so" PARENT_SCOPE)
37 |
38 | list(APPEND FLUTTER_LIBRARY_HEADERS
39 | "fl_basic_message_channel.h"
40 | "fl_binary_codec.h"
41 | "fl_binary_messenger.h"
42 | "fl_dart_project.h"
43 | "fl_engine.h"
44 | "fl_json_message_codec.h"
45 | "fl_json_method_codec.h"
46 | "fl_message_codec.h"
47 | "fl_method_call.h"
48 | "fl_method_channel.h"
49 | "fl_method_codec.h"
50 | "fl_method_response.h"
51 | "fl_plugin_registrar.h"
52 | "fl_plugin_registry.h"
53 | "fl_standard_message_codec.h"
54 | "fl_standard_method_codec.h"
55 | "fl_string_codec.h"
56 | "fl_value.h"
57 | "fl_view.h"
58 | "flutter_linux.h"
59 | )
60 | list_prepend(FLUTTER_LIBRARY_HEADERS "${EPHEMERAL_DIR}/flutter_linux/")
61 | add_library(flutter INTERFACE)
62 | target_include_directories(flutter INTERFACE
63 | "${EPHEMERAL_DIR}"
64 | )
65 | target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}")
66 | target_link_libraries(flutter INTERFACE
67 | PkgConfig::GTK
68 | PkgConfig::GLIB
69 | PkgConfig::GIO
70 | PkgConfig::BLKID
71 | PkgConfig::LZMA
72 | )
73 | add_dependencies(flutter flutter_assemble)
74 |
75 | # === Flutter tool backend ===
76 | # _phony_ is a non-existent file to force this command to run every time,
77 | # since currently there's no way to get a full input/output list from the
78 | # flutter tool.
79 | add_custom_command(
80 | OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS}
81 | ${CMAKE_CURRENT_BINARY_DIR}/_phony_
82 | COMMAND ${CMAKE_COMMAND} -E env
83 | ${FLUTTER_TOOL_ENVIRONMENT}
84 | "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.sh"
85 | linux-x64 ${CMAKE_BUILD_TYPE}
86 | VERBATIM
87 | )
88 | add_custom_target(flutter_assemble DEPENDS
89 | "${FLUTTER_LIBRARY}"
90 | ${FLUTTER_LIBRARY_HEADERS}
91 | )
92 |
--------------------------------------------------------------------------------
/InterpreterVisualizer/src/main/java/simpleinterpreter/Stmt.java:
--------------------------------------------------------------------------------
1 | package simpleinterpreter;
2 |
3 | import java.util.List;
4 |
5 | abstract class Stmt {
6 | interface Visitor {
7 | R visitBlockStmt(Block stmt);
8 |
9 | R visitExpressionStmt(Expression stmt);
10 |
11 | R visitIfStmt(If stmt);
12 |
13 | R visitPrintStmt(Print stmt);
14 |
15 | R visitVarStmt(Var stmt);
16 |
17 | R visitWhileStmt(While stmt);
18 | }
19 |
20 | int astNodeIndex;
21 |
22 | static class Block extends Stmt {
23 | Block(List statements, int astNodeIndex) {
24 | this.statements = statements;
25 | this.astNodeIndex = astNodeIndex;
26 | }
27 |
28 | @Override
29 | R accept(Visitor visitor) {
30 | return visitor.visitBlockStmt(this);
31 | }
32 |
33 | final List statements;
34 | }
35 |
36 | static class Expression extends Stmt {
37 | Expression(Expr expression, int astNodeIndex) {
38 | this.expression = expression;
39 | this.astNodeIndex = astNodeIndex;
40 | }
41 |
42 | @Override
43 | R accept(Visitor visitor) {
44 | return visitor.visitExpressionStmt(this);
45 | }
46 |
47 | final Expr expression;
48 | }
49 |
50 | static class If extends Stmt {
51 | If(Expr condition,
52 | Stmt thenBranch,
53 | Stmt elseBranch,
54 | int astNodeIndex) {
55 | this.condition = condition;
56 | this.thenBranch = thenBranch;
57 | this.elseBranch = elseBranch;
58 | this.astNodeIndex = astNodeIndex;
59 | }
60 |
61 | @Override
62 | R accept(Visitor visitor) {
63 | return visitor.visitIfStmt(this);
64 | }
65 |
66 | final Expr condition;
67 | final Stmt thenBranch;
68 | final Stmt elseBranch;
69 | }
70 |
71 | static class Print extends Stmt {
72 | Print(Expr expression, int astNodeIndex) {
73 | this.expression = expression;
74 | this.astNodeIndex = astNodeIndex;
75 | }
76 |
77 | @Override
78 | R accept(Visitor visitor) {
79 | return visitor.visitPrintStmt(this);
80 | }
81 |
82 | final Expr expression;
83 | }
84 |
85 | static class Var extends Stmt {
86 | Var(Token name, Expr initializer, int astNodeIndex) {
87 | this.name = name;
88 | this.initializer = initializer;
89 | this.astNodeIndex = astNodeIndex;
90 | }
91 |
92 | @Override
93 | R accept(Visitor visitor) {
94 | return visitor.visitVarStmt(this);
95 | }
96 |
97 | final Token name;
98 | final Expr initializer;
99 | }
100 |
101 | static class While extends Stmt {
102 | While(Expr condition, Stmt body, int astNodeIndex) {
103 | this.condition = condition;
104 | this.body = body;
105 | this.astNodeIndex = astNodeIndex;
106 | }
107 |
108 | @Override
109 | R accept(Visitor visitor) {
110 | return visitor.visitWhileStmt(this);
111 | }
112 |
113 | final Expr condition;
114 | final Stmt body;
115 | }
116 |
117 |
118 | abstract R accept(Visitor visitor);
119 | }
--------------------------------------------------------------------------------
/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: flutterdesktopapp
2 | description: A new Flutter project.
3 |
4 | # The following line prevents the package from being accidentally published to
5 | # pub.dev using `pub publish`. This is preferred for private packages.
6 | publish_to: 'none' # Remove this line if you wish to publish to pub.dev
7 |
8 | # The following defines the version and build number for your application.
9 | # A version number is three numbers separated by dots, like 1.2.43
10 | # followed by an optional build number separated by a +.
11 | # Both the version and the builder number may be overridden in flutter
12 | # build by specifying --build-name and --build-number, respectively.
13 | # In Android, build-name is used as versionName while build-number used as versionCode.
14 | # Read more about Android versioning at https://developer.android.com/studio/publish/versioning
15 | # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
16 | # Read more about iOS versioning at
17 | # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
18 | version: 1.0.0+1
19 |
20 | environment:
21 | sdk: ">=2.7.0 <3.0.0"
22 |
23 | dependencies:
24 | flutter:
25 | sdk: flutter
26 |
27 |
28 | # The following adds the Cupertino Icons font to your application.
29 | # Use with the CupertinoIcons class for iOS style icons.
30 | cupertino_icons: ^1.0.2
31 | provider: ^5.0.0
32 | path_provider: ^2.0.2
33 | flutter_progress_hud: ^2.0.0
34 | graphite: ^0.3.0
35 | bidirectional_listview: ^1.0.2+4
36 | http: ^0.13.3
37 | screenshot: ^1.2.1
38 |
39 | window_size:
40 | git:
41 | url: git://github.com/google/flutter-desktop-embedding.git
42 | path: plugins/window_size
43 | ref: fd519be1e8398c6b6c2062c2447bac960a71bc02
44 |
45 |
46 | dev_dependencies:
47 | flutter_test:
48 | sdk: flutter
49 |
50 | # For information on the generic Dart part of this file, see the
51 | # following page: https://dart.dev/tools/pub/pubspec
52 |
53 | # The following section is specific to Flutter.
54 | flutter:
55 |
56 | # The following line ensures that the Material Icons font is
57 | # included with your application, so that you can use the icons in
58 | # the material Icons class.
59 | uses-material-design: true
60 |
61 | # To add assets to your application, add an assets section, like this:
62 | assets:
63 | - assets/tokens_file.txt
64 | # - images/a_dot_ham.jpeg
65 |
66 | # An image asset can refer to one or more resolution-specific "variants", see
67 | # https://flutter.dev/assets-and-images/#resolution-aware.
68 |
69 | # For details regarding adding assets from package dependencies, see
70 | # https://flutter.dev/assets-and-images/#from-packages
71 |
72 | # To add custom fonts to your application, add a fonts section here,
73 | # in this "flutter" section. Each entry in this list should have a
74 | # "family" key with the font family name, and a "fonts" key with a
75 | # list giving the asset and other descriptors for the font. For
76 | # example:
77 | # fonts:
78 | # - family: Schyler
79 | # fonts:
80 | # - asset: fonts/Schyler-Regular.ttf
81 | # - asset: fonts/Schyler-Italic.ttf
82 | # style: italic
83 | # - family: Trajan Pro
84 | # fonts:
85 | # - asset: fonts/TrajanPro.ttf
86 | # - asset: fonts/TrajanPro_Bold.ttf
87 | # weight: 700
88 | #
89 | # For details regarding fonts from package dependencies,
90 | # see https://flutter.dev/custom-fonts/#from-packages
91 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
54 |
56 |
62 |
63 |
64 |
65 |
66 |
67 |
73 |
75 |
81 |
82 |
83 |
84 |
86 |
87 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/InterpreterVisualizer/src/main/java/simpleinterpreter/Expr.java:
--------------------------------------------------------------------------------
1 | package simpleinterpreter;
2 |
3 | abstract class Expr {
4 | interface Visitor {
5 | R visitAssignExpr(Assign expr);
6 |
7 | R visitBinaryExpr(Binary expr);
8 |
9 | R visitGroupingExpr(Grouping expr);
10 |
11 | R visitLiteralExpr(Literal expr);
12 |
13 | R visitLogicalExpr(Logical expr);
14 |
15 | R visitUnaryExpr(Unary expr);
16 |
17 | R visitVariableExpr(Variable expr);
18 | }
19 |
20 | int astNodeIndex;
21 |
22 | static class Assign extends Expr {
23 | Assign(Token name, Expr value, int astNodeIndex) {
24 | this.name = name;
25 | this.value = value;
26 | this.astNodeIndex = astNodeIndex;
27 | }
28 |
29 | @Override
30 | R accept(Visitor visitor) {
31 | return visitor.visitAssignExpr(this);
32 | }
33 |
34 | final Token name;
35 | final Expr value;
36 | }
37 |
38 | static class Binary extends Expr {
39 | Binary(Expr left, Token operator, Expr right, int astNodeIndex) {
40 | this.left = left;
41 | this.operator = operator;
42 | this.right = right;
43 | this.astNodeIndex = astNodeIndex;
44 | }
45 |
46 | @Override
47 | R accept(Visitor visitor) {
48 | return visitor.visitBinaryExpr(this);
49 | }
50 |
51 | final Expr left;
52 | final Token operator;
53 | final Expr right;
54 | }
55 |
56 | static class Grouping extends Expr {
57 | Grouping(Expr expression, int astNodeIndex) {
58 | this.expression = expression;
59 | this.astNodeIndex = astNodeIndex;
60 | }
61 |
62 | @Override
63 | R accept(Visitor visitor) {
64 | return visitor.visitGroupingExpr(this);
65 | }
66 |
67 | final Expr expression;
68 | }
69 |
70 | static class Literal extends Expr {
71 | Literal(Object value, int astNodeIndex) {
72 | this.value = value;
73 | this.astNodeIndex = astNodeIndex;
74 | }
75 |
76 | @Override
77 | R accept(Visitor visitor) {
78 | return visitor.visitLiteralExpr(this);
79 | }
80 |
81 | final Object value;
82 | }
83 |
84 | static class Logical extends Expr {
85 | Logical(Expr left, Token operator, Expr right, int astNodeIndex) {
86 | this.left = left;
87 | this.operator = operator;
88 | this.right = right;
89 | this.astNodeIndex = astNodeIndex;
90 | }
91 |
92 | @Override
93 | R accept(Visitor visitor) {
94 | return visitor.visitLogicalExpr(this);
95 | }
96 |
97 | final Expr left;
98 | final Token operator;
99 | final Expr right;
100 | }
101 |
102 | static class Unary extends Expr {
103 | Unary(Token operator, Expr right, int astNodeIndex) {
104 | this.operator = operator;
105 | this.right = right;
106 | this.astNodeIndex = astNodeIndex;
107 | }
108 |
109 | @Override
110 | R accept(Visitor visitor) {
111 | return visitor.visitUnaryExpr(this);
112 | }
113 |
114 | final Token operator;
115 | final Expr right;
116 | }
117 |
118 | static class Variable extends Expr {
119 | Variable(Token name, int astNodeIndex) {
120 | this.name = name;
121 | this.astNodeIndex = astNodeIndex;
122 | }
123 |
124 | @Override
125 | R accept(Visitor visitor) {
126 | return visitor.visitVariableExpr(this);
127 | }
128 |
129 | final Token name;
130 | }
131 |
132 | abstract R accept(Visitor visitor);
133 | }
--------------------------------------------------------------------------------
/android/app/build.gradle:
--------------------------------------------------------------------------------
1 | //def localProperties = new Properties()
2 | //def localPropertiesFile = rootProject.file('local.properties')
3 | //if (localPropertiesFile.exists()) {
4 | // localPropertiesFile.withReader('UTF-8') { reader ->
5 | // localProperties.load(reader)
6 | // }
7 | //}
8 | //
9 | //def flutterRoot = localProperties.getProperty('flutter.sdk')
10 | //if (flutterRoot == null) {
11 | // throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
12 | //}
13 | //
14 | //def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
15 | //if (flutterVersionCode == null) {
16 | // flutterVersionCode = '1'
17 | //}
18 | //
19 | //def flutterVersionName = localProperties.getProperty('flutter.versionName')
20 | //if (flutterVersionName == null) {
21 | // flutterVersionName = '1.0'
22 | //}
23 | //
24 | //apply plugin: 'com.android.application'
25 | //apply plugin: 'kotlin-android'
26 | //apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
27 | //
28 | //android {
29 | // compileSdkVersion 30
30 | //
31 | // sourceSets {
32 | // main.java.srcDirs += 'src/main/kotlin'
33 | // }
34 | //
35 | // defaultConfig {
36 | // // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
37 | // applicationId "com.example.flutterdesktopapp"
38 | // minSdkVersion 16
39 | // targetSdkVersion 30
40 | // versionCode flutterVersionCode.toInteger()
41 | // versionName flutterVersionName
42 | // }
43 | //
44 | // buildTypes {
45 | // release {
46 | // // TODO: Add your own signing config for the release build.
47 | // // Signing with the debug keys for now, so `flutter run --release` works.
48 | // signingConfig signingConfigs.debug
49 | // }
50 | // }
51 | //}
52 | //
53 | //flutter {
54 | // source '../..'
55 | //}
56 | //
57 | //dependencies {
58 | // implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
59 | //}
60 | //
61 | //
62 | //*****************************
63 |
64 | def localProperties = new Properties()
65 | def localPropertiesFile = rootProject.file('local.properties')
66 | if (localPropertiesFile.exists()) {
67 | localPropertiesFile.withReader('UTF-8') { reader ->
68 | localProperties.load(reader)
69 | }
70 | }
71 |
72 | def flutterRoot = localProperties.getProperty('flutter.sdk')
73 | if (flutterRoot == null) {
74 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
75 | }
76 |
77 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
78 | if (flutterVersionCode == null) {
79 | flutterVersionCode = '1'
80 | }
81 |
82 | def flutterVersionName = localProperties.getProperty('flutter.versionName')
83 | if (flutterVersionName == null) {
84 | flutterVersionName = '1.0'
85 | }
86 |
87 | apply plugin: 'com.android.application'
88 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
89 |
90 | android {
91 | compileSdkVersion 30
92 |
93 | defaultConfig {
94 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
95 | applicationId "com.example.flutterdesktopapp"
96 | minSdkVersion 16
97 | targetSdkVersion 30
98 | versionCode flutterVersionCode.toInteger()
99 | versionName flutterVersionName
100 | }
101 |
102 | buildTypes {
103 | release {
104 | // TODO: Add your own signing config for the release build.
105 | // Signing with the debug keys for now, so `flutter run --release` works.
106 | signingConfig signingConfigs.debug
107 | }
108 | }
109 | }
110 |
111 | flutter {
112 | source '../..'
113 | }
114 |
115 |
116 |
--------------------------------------------------------------------------------
/linux/my_application.cc:
--------------------------------------------------------------------------------
1 | #include "my_application.h"
2 |
3 | #include
4 | #ifdef GDK_WINDOWING_X11
5 | #include
6 | #endif
7 |
8 | #include "flutter/generated_plugin_registrant.h"
9 |
10 | struct _MyApplication {
11 | GtkApplication parent_instance;
12 | char** dart_entrypoint_arguments;
13 | };
14 |
15 | G_DEFINE_TYPE(MyApplication, my_application, GTK_TYPE_APPLICATION)
16 |
17 | // Implements GApplication::activate.
18 | static void my_application_activate(GApplication* application) {
19 | MyApplication* self = MY_APPLICATION(application);
20 | GtkWindow* window =
21 | GTK_WINDOW(gtk_application_window_new(GTK_APPLICATION(application)));
22 |
23 | // Use a header bar when running in GNOME as this is the common style used
24 | // by applications and is the setup most users will be using (e.g. Ubuntu
25 | // desktop).
26 | // If running on X and not using GNOME then just use a traditional title bar
27 | // in case the window manager does more exotic layout, e.g. tiling.
28 | // If running on Wayland assume the header bar will work (may need changing
29 | // if future cases occur).
30 | gboolean use_header_bar = TRUE;
31 | #ifdef GDK_WINDOWING_X11
32 | GdkScreen *screen = gtk_window_get_screen(window);
33 | if (GDK_IS_X11_SCREEN(screen)) {
34 | const gchar* wm_name = gdk_x11_screen_get_window_manager_name(screen);
35 | if (g_strcmp0(wm_name, "GNOME Shell") != 0) {
36 | use_header_bar = FALSE;
37 | }
38 | }
39 | #endif
40 | if (use_header_bar) {
41 | GtkHeaderBar *header_bar = GTK_HEADER_BAR(gtk_header_bar_new());
42 | gtk_widget_show(GTK_WIDGET(header_bar));
43 | gtk_header_bar_set_title(header_bar, "flutterdesktopapp");
44 | gtk_header_bar_set_show_close_button(header_bar, TRUE);
45 | gtk_window_set_titlebar(window, GTK_WIDGET(header_bar));
46 | }
47 | else {
48 | gtk_window_set_title(window, "flutterdesktopapp");
49 | }
50 |
51 | gtk_window_set_default_size(window, 1280, 720);
52 | gtk_widget_show(GTK_WIDGET(window));
53 |
54 | g_autoptr(FlDartProject) project = fl_dart_project_new();
55 | fl_dart_project_set_dart_entrypoint_arguments(project, self->dart_entrypoint_arguments);
56 |
57 | FlView* view = fl_view_new(project);
58 | gtk_widget_show(GTK_WIDGET(view));
59 | gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(view));
60 |
61 | fl_register_plugins(FL_PLUGIN_REGISTRY(view));
62 |
63 | gtk_widget_grab_focus(GTK_WIDGET(view));
64 | }
65 |
66 | // Implements GApplication::local_command_line.
67 | static gboolean my_application_local_command_line(GApplication* application, gchar ***arguments, int *exit_status) {
68 | MyApplication* self = MY_APPLICATION(application);
69 | // Strip out the first argument as it is the binary name.
70 | self->dart_entrypoint_arguments = g_strdupv(*arguments + 1);
71 |
72 | g_autoptr(GError) error = nullptr;
73 | if (!g_application_register(application, nullptr, &error)) {
74 | g_warning("Failed to register: %s", error->message);
75 | *exit_status = 1;
76 | return TRUE;
77 | }
78 |
79 | g_application_activate(application);
80 | *exit_status = 0;
81 |
82 | return TRUE;
83 | }
84 |
85 | // Implements GObject::dispose.
86 | static void my_application_dispose(GObject *object) {
87 | MyApplication* self = MY_APPLICATION(object);
88 | g_clear_pointer(&self->dart_entrypoint_arguments, g_strfreev);
89 | G_OBJECT_CLASS(my_application_parent_class)->dispose(object);
90 | }
91 |
92 | static void my_application_class_init(MyApplicationClass* klass) {
93 | G_APPLICATION_CLASS(klass)->activate = my_application_activate;
94 | G_APPLICATION_CLASS(klass)->local_command_line = my_application_local_command_line;
95 | G_OBJECT_CLASS(klass)->dispose = my_application_dispose;
96 | }
97 |
98 | static void my_application_init(MyApplication* self) {}
99 |
100 | MyApplication* my_application_new() {
101 | return MY_APPLICATION(g_object_new(my_application_get_type(),
102 | "application-id", APPLICATION_ID,
103 | nullptr));
104 | }
105 |
--------------------------------------------------------------------------------
/linux/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.10)
2 | project(runner LANGUAGES CXX)
3 |
4 | set(BINARY_NAME "flutterdesktopapp")
5 | set(APPLICATION_ID "com.example.flutterdesktopapp")
6 |
7 | cmake_policy(SET CMP0063 NEW)
8 |
9 | set(CMAKE_INSTALL_RPATH "$ORIGIN/lib")
10 |
11 | # Configure build options.
12 | if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
13 | set(CMAKE_BUILD_TYPE "Debug" CACHE
14 | STRING "Flutter build mode" FORCE)
15 | set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
16 | "Debug" "Profile" "Release")
17 | endif()
18 |
19 | # Compilation settings that should be applied to most targets.
20 | function(APPLY_STANDARD_SETTINGS TARGET)
21 | target_compile_features(${TARGET} PUBLIC cxx_std_14)
22 | target_compile_options(${TARGET} PRIVATE -Wall -Werror)
23 | target_compile_options(${TARGET} PRIVATE "$<$>:-O3>")
24 | target_compile_definitions(${TARGET} PRIVATE "$<$>:NDEBUG>")
25 | endfunction()
26 |
27 | set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter")
28 |
29 | # Flutter library and tool build rules.
30 | add_subdirectory(${FLUTTER_MANAGED_DIR})
31 |
32 | # System-level dependencies.
33 | find_package(PkgConfig REQUIRED)
34 | pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0)
35 |
36 | add_definitions(-DAPPLICATION_ID="${APPLICATION_ID}")
37 |
38 | # Application build
39 | add_executable(${BINARY_NAME}
40 | "main.cc"
41 | "my_application.cc"
42 | "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc"
43 | )
44 | apply_standard_settings(${BINARY_NAME})
45 | target_link_libraries(${BINARY_NAME} PRIVATE flutter)
46 | target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK)
47 | add_dependencies(${BINARY_NAME} flutter_assemble)
48 | # Only the install-generated bundle's copy of the executable will launch
49 | # correctly, since the resources must in the right relative locations. To avoid
50 | # people trying to run the unbundled copy, put it in a subdirectory instead of
51 | # the default top-level location.
52 | set_target_properties(${BINARY_NAME}
53 | PROPERTIES
54 | RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/intermediates_do_not_run"
55 | )
56 |
57 | # Generated plugin build rules, which manage building the plugins and adding
58 | # them to the application.
59 | include(flutter/generated_plugins.cmake)
60 |
61 |
62 | # === Installation ===
63 | # By default, "installing" just makes a relocatable bundle in the build
64 | # directory.
65 | set(BUILD_BUNDLE_DIR "${PROJECT_BINARY_DIR}/bundle")
66 | if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
67 | set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE)
68 | endif()
69 |
70 | # Start with a clean build bundle directory every time.
71 | install(CODE "
72 | file(REMOVE_RECURSE \"${BUILD_BUNDLE_DIR}/\")
73 | " COMPONENT Runtime)
74 |
75 | set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data")
76 | set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib")
77 |
78 | install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}"
79 | COMPONENT Runtime)
80 |
81 | install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}"
82 | COMPONENT Runtime)
83 |
84 | install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
85 | COMPONENT Runtime)
86 |
87 | if(PLUGIN_BUNDLED_LIBRARIES)
88 | install(FILES "${PLUGIN_BUNDLED_LIBRARIES}"
89 | DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
90 | COMPONENT Runtime)
91 | endif()
92 |
93 | # Fully re-copy the assets directory on each build to avoid having stale files
94 | # from a previous install.
95 | set(FLUTTER_ASSET_DIR_NAME "flutter_assets")
96 | install(CODE "
97 | file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\")
98 | " COMPONENT Runtime)
99 | install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}"
100 | DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime)
101 |
102 | # Install the AOT library on non-Debug builds only.
103 | if(NOT CMAKE_BUILD_TYPE MATCHES "Debug")
104 | install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
105 | COMPONENT Runtime)
106 | endif()
107 |
--------------------------------------------------------------------------------
/lib/utils/app_data.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/cupertino.dart';
2 | import 'package:flutterdesktopapp/models/Ast.dart';
3 | import 'package:flutterdesktopapp/models/statement.dart';
4 | import 'package:flutterdesktopapp/models/tokens.dart';
5 |
6 | class AppData with ChangeNotifier {
7 | bool _isVisualized = false;
8 | bool _isVisualizationReady = false;
9 |
10 | bool get isVisualizationReady => _isVisualizationReady;
11 |
12 | set isVisualizationReady(bool value) {
13 | _isVisualizationReady = value;
14 | notifyListeners();
15 | }
16 |
17 | bool atLeastOneCircle() {
18 | return (circleOneClicked || circleTwoClicked || circleThreeClicked);
19 | }
20 |
21 | bool _cirlcleOneClicked = false;
22 | bool _circleTwoClicked = false;
23 | bool _circleThreeClicked = false;
24 | bool _circleFourClicked = false;
25 | bool _tokensChange = false;
26 |
27 | List _tokensColors = [];
28 | List _tokensIndices = [];
29 | List _tokensList = [];
30 |
31 | List _parsedStatementsList = [];
32 | List _astsList = [];
33 |
34 | List get astsList => _astsList;
35 |
36 | set astsList(List value) {
37 | _astsList = value;
38 | }
39 |
40 | List get parsedStatementsList => _parsedStatementsList;
41 |
42 | set parsedStatementsList(List value) {
43 | _parsedStatementsList = value;
44 | }
45 |
46 | int _visualizedStatementIndex = 0;
47 |
48 | int get visualizedStatementIndex => _visualizedStatementIndex;
49 |
50 | void resetVisualizerStatementIndex() {
51 | _visualizedStatementIndex = 0;
52 | }
53 |
54 | set visualizedStatementIndex(int value) {
55 | _visualizedStatementIndex = value;
56 | notifyListeners();
57 | }
58 |
59 | // List _jsonList = [];
60 | // List _newNodeID = [];
61 | // List _nodeDataList = [];
62 |
63 | // List get jsonList => _jsonList;
64 |
65 | // set jsonList(List value) {
66 | // _jsonList = value;
67 | // }
68 |
69 | void refreshTokensChange() {
70 | _tokensChange = !_tokensChange;
71 | notifyListeners();
72 | }
73 |
74 | bool get tokensChange => _tokensChange;
75 |
76 | set tokensList(List value) {
77 | _tokensList = value;
78 | }
79 |
80 | List get tokensList => _tokensList;
81 |
82 | List get tokensIndices => _tokensIndices;
83 |
84 | set tokensIndices(List value) {
85 | _tokensIndices = value;
86 | }
87 |
88 | List get tokensColors => _tokensColors;
89 |
90 | set tokensColors(List value) {
91 | _tokensColors = value;
92 | notifyListeners();
93 | }
94 |
95 | TextEditingController _editingController = TextEditingController();
96 |
97 | void changeCircleOneState() {
98 | if (_cirlcleOneClicked) {
99 | _cirlcleOneClicked = false;
100 | } else {
101 | _cirlcleOneClicked = true;
102 | }
103 | notifyListeners();
104 | }
105 |
106 | void changeCircleTwoState() {
107 | if (_circleTwoClicked) {
108 | _circleTwoClicked = false;
109 | } else {
110 | _circleTwoClicked = true;
111 | }
112 | notifyListeners();
113 | }
114 |
115 | void changeCircleThreeState() {
116 | if (_circleThreeClicked) {
117 | _circleThreeClicked = false;
118 | } else {
119 | _circleThreeClicked = true;
120 | }
121 | notifyListeners();
122 | }
123 |
124 | void changeCircleFourState() {
125 | if (_circleFourClicked) {
126 | _circleFourClicked = false;
127 | } else {
128 | _circleFourClicked = true;
129 | }
130 | notifyListeners();
131 | }
132 |
133 | void visualize() {
134 | _isVisualized = true;
135 | notifyListeners();
136 | }
137 |
138 | bool get circleOneClicked => _cirlcleOneClicked;
139 |
140 | bool get circleTwoClicked => _circleTwoClicked;
141 |
142 | bool get circleThreeClicked => _circleThreeClicked;
143 |
144 | bool get circleFourClicked => _circleFourClicked;
145 |
146 | bool get isVisualized => _isVisualized;
147 |
148 | TextEditingController get editingController => _editingController;
149 |
150 | // List get newNodeID => _newNodeID;
151 |
152 | // set newNodeID(List value) {
153 | // _newNodeID = value;
154 | // }
155 |
156 | // List get nodeDataList => _nodeDataList;
157 |
158 | // set nodeDataList(List value) {
159 | // _nodeDataList = value;
160 | // }
161 | }
162 |
--------------------------------------------------------------------------------
/lib/ui_elements/freescrollview.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/gestures.dart';
2 | import 'package:flutter/material.dart';
3 |
4 | class FreeScrollView extends StatefulWidget {
5 | final Widget child;
6 | final ScrollPhysics physics;
7 |
8 | const FreeScrollView(
9 | {Key key,
10 | this.physics = const ClampingScrollPhysics(),
11 | @required this.child})
12 | : super(key: key);
13 |
14 | @override
15 | State createState() => _FreeScrollViewState();
16 | }
17 |
18 | class _FreeScrollViewState extends State {
19 | final ScrollController _verticalController = ScrollController();
20 | final ScrollController _horizontalController = ScrollController();
21 | final Map _gestureRecognizers =
22 | {};
23 |
24 | @override
25 | void initState() {
26 | super.initState();
27 | _gestureRecognizers[PanGestureRecognizer] =
28 | GestureRecognizerFactoryWithHandlers(
29 | () => PanGestureRecognizer(),
30 | (instance) => instance
31 | ..onDown = _handleDragDown
32 | ..onStart = _handleDragStart
33 | ..onUpdate = _handleDragUpdate
34 | ..onEnd = _handleDragEnd
35 | ..onCancel = _handleDragCancel
36 | ..minFlingDistance = widget.physics.minFlingDistance
37 | ..minFlingVelocity = widget.physics.minFlingVelocity
38 | ..maxFlingVelocity = widget.physics.maxFlingVelocity
39 | ..velocityTrackerBuilder = ScrollConfiguration.of(context)
40 | .velocityTrackerBuilder(context)
41 | ..dragStartBehavior = DragStartBehavior.start);
42 | }
43 |
44 | @override
45 | Widget build(BuildContext context) => Stack(children: [
46 | SingleChildScrollView(
47 | scrollDirection: Axis.horizontal,
48 | controller: _horizontalController,
49 | physics: widget.physics,
50 | child: SingleChildScrollView(
51 | scrollDirection: Axis.vertical,
52 | // ignore: avoid_redundant_argument_values
53 | controller: _verticalController,
54 | physics: widget.physics,
55 | child: widget.child)),
56 | Positioned.fill(
57 | child: RawGestureDetector(
58 | gestures: _gestureRecognizers,
59 | behavior: HitTestBehavior.opaque,
60 | excludeFromSemantics: true,
61 | )),
62 | ]);
63 |
64 | Drag _horizontalDrag;
65 | Drag _verticalDrag;
66 | ScrollHoldController _horizontalHold;
67 | ScrollHoldController _verticalHold;
68 |
69 | void _handleDragDown(DragDownDetails details) {
70 | _horizontalHold =
71 | _horizontalController.position.hold(() => _horizontalHold = null);
72 | _verticalHold =
73 | _verticalController.position.hold(() => _verticalHold = null);
74 | }
75 |
76 | void _handleDragStart(DragStartDetails details) {
77 | _horizontalDrag = _horizontalController.position
78 | .drag(details, () => _horizontalDrag = null);
79 | _verticalDrag =
80 | _verticalController.position.drag(details, () => _verticalDrag = null);
81 | }
82 |
83 | void _handleDragUpdate(DragUpdateDetails details) {
84 | _horizontalDrag?.update(DragUpdateDetails(
85 | sourceTimeStamp: details.sourceTimeStamp,
86 | delta: Offset(details.delta.dx, 0),
87 | primaryDelta: details.delta.dx,
88 | globalPosition: details.globalPosition));
89 | _verticalDrag?.update(DragUpdateDetails(
90 | sourceTimeStamp: details.sourceTimeStamp,
91 | delta: Offset(0, details.delta.dy),
92 | primaryDelta: details.delta.dy,
93 | globalPosition: details.globalPosition));
94 | }
95 |
96 | void _handleDragEnd(DragEndDetails details) {
97 | _horizontalDrag?.end(DragEndDetails(
98 | velocity: details.velocity,
99 | primaryVelocity: details.velocity.pixelsPerSecond.dx));
100 | _verticalDrag?.end(DragEndDetails(
101 | velocity: details.velocity,
102 | primaryVelocity: details.velocity.pixelsPerSecond.dy));
103 | }
104 |
105 | void _handleDragCancel() {
106 | _horizontalHold?.cancel();
107 | _horizontalDrag?.cancel();
108 | _verticalHold?.cancel();
109 | _verticalDrag?.cancel();
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/lib/ui_elements/token_item.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutterdesktopapp/utils/app_data.dart';
3 | import 'package:flutterdesktopapp/utils/constants.dart';
4 | import 'package:flutterdesktopapp/utils/utilities_provider.dart';
5 | import 'package:provider/provider.dart';
6 |
7 | import 'colored_card_box.dart';
8 |
9 | class TokenItem extends StatefulWidget {
10 | final int index;
11 | final double duration;
12 | final AnimationController animationController;
13 |
14 | TokenItem(this.index, this.duration, this.animationController);
15 |
16 | @override
17 | _TokenItemState createState() => _TokenItemState();
18 | }
19 |
20 | class _TokenItemState extends State {
21 | Animation animation;
22 | Animation animationColor;
23 | double start;
24 | double end;
25 | bool showErrors = true;
26 |
27 | @override
28 | void initState() {
29 | print(widget.index.toString() + " signing in");
30 | super.initState();
31 | start = (widget.duration * widget.index).toDouble();
32 | end = start + widget.duration;
33 | // end = (end > 1.0 ? 1.0 : end);
34 | print("START $start , end $end");
35 |
36 | animation = Tween(
37 | begin: 0.0,
38 | end: 1.0,
39 | ).animate(
40 | CurvedAnimation(
41 | parent: widget.animationController,
42 | curve: Interval(
43 | start,
44 | end,
45 | curve: Curves.easeInOutCirc,
46 | ),
47 | ),
48 | );
49 |
50 | var appData = Provider.of(context, listen: false);
51 | var tokenIndex = appData.tokensIndices[widget.index];
52 | var tokenGoalColor = appData.tokensColors[tokenIndex];
53 |
54 | animationColor = ColorTween(
55 | begin: Colors.black,
56 | end: tokenGoalColor,
57 | ).animate(
58 | CurvedAnimation(
59 | parent: widget.animationController,
60 | curve: Interval(
61 | start,
62 | end,
63 | curve: Curves.easeInOutCirc,
64 | ),
65 | ),
66 | );
67 |
68 | widget.animationController.addListener(() {
69 | if (this.mounted) setState(() {});
70 | });
71 | }
72 |
73 | // @override
74 | void dispose() {
75 | print("Token Disposed");
76 | // // TODO: implement dispose
77 | super.dispose();
78 | }
79 |
80 | @override
81 | Widget build(BuildContext context) {
82 | var appData = Provider.of(context);
83 | final utilsProvider = Provider.of(context);
84 |
85 | var tokensList = appData.tokensList;
86 | var tokenIndex = appData.tokensIndices[widget.index];
87 | var token = tokensList[widget.index];
88 |
89 | if (tokenIndex < utilsProvider.richTextList.length) {
90 | utilsProvider.richTextList[tokenIndex][1] = animationColor.value;
91 | }
92 |
93 | WidgetsBinding.instance.addPostFrameCallback((_) {
94 | if (showErrors && animation.value >= start) {
95 | for (var error in token.errors) {
96 | utilsProvider.addConsoleMessage(error, 0);
97 | }
98 | showErrors = false;
99 | }
100 |
101 | var temp = List.from(utilsProvider.richTextList);
102 | utilsProvider.richTextList = temp;
103 | });
104 |
105 | return Opacity(
106 | opacity: animation.value,
107 | child: ColoredCardBox(
108 | color: animationColor.value,
109 | child: Row(
110 | mainAxisAlignment: MainAxisAlignment.spaceBetween,
111 | children: [
112 | SizedBox(
113 | child: Container(
114 | child: Text("${tokensList[widget.index].tokenType}",
115 | style: text_style_table_row)),
116 | width: 125.0,
117 | ),
118 | SizedBox(
119 | child: Container(
120 | child: Text("${tokensList[widget.index].lexeme}",
121 | style: text_style_table_row)),
122 | width: 80.0,
123 | ),
124 | SizedBox(
125 | child: Container(
126 | child: Text("${tokensList[widget.index].literal}",
127 | style: text_style_table_row)),
128 | width: 80.0,
129 | ),
130 | SizedBox(
131 | child: Container(
132 | child: Text("${tokensList[widget.index].line}",
133 | style: text_style_table_row)),
134 | width: 80.0,
135 | ),
136 | ],
137 | ),
138 | ),
139 | );
140 | }
141 | }
142 |
--------------------------------------------------------------------------------
/lib/screens/ast_graph.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutterdesktopapp/utils/app_data.dart';
3 | import 'package:flutterdesktopapp/utils/constants.dart';
4 | import 'package:flutterdesktopapp/utils/utilities_provider.dart';
5 | import 'package:graphite/core/matrix.dart';
6 | import 'package:graphite/graphite.dart';
7 | import 'package:provider/provider.dart';
8 |
9 | class ASTGraph extends StatefulWidget {
10 | final int statementIndex;
11 | final int index;
12 | final double duration;
13 | final AnimationController animationController;
14 |
15 | ASTGraph(
16 | this.index, this.statementIndex, this.animationController, this.duration);
17 |
18 | @override
19 | _ASTGraphState createState() => _ASTGraphState();
20 | }
21 |
22 | class _ASTGraphState extends State {
23 | Animation animation;
24 | Animation animationColor;
25 | double start;
26 | double end;
27 | var showErrors = true;
28 | var showOutput = true;
29 |
30 | @override
31 | void initState() {
32 | print(widget.index.toString() + " signing in");
33 | super.initState();
34 | start = (widget.duration * widget.index).toDouble();
35 | end = start + widget.duration;
36 | print("START $start , end $end");
37 |
38 | animation = Tween(
39 | begin: 0.0,
40 | end: 1.0,
41 | ).animate(
42 | CurvedAnimation(
43 | parent: widget.animationController,
44 | curve: Interval(
45 | start,
46 | end,
47 | curve: Curves.easeInOutCirc,
48 | ),
49 | ),
50 | );
51 |
52 | widget.animationController.addListener(() {
53 | if (this.mounted) setState(() {});
54 | });
55 | }
56 |
57 | @override
58 | void dispose() {
59 | print("AST Graph Disposed");
60 | // TODO: implement dispose
61 | super.dispose();
62 | }
63 |
64 | @override
65 | Widget build(BuildContext context) {
66 | var appData = Provider.of(context, listen: false);
67 | final utilsProvider =
68 | Provider.of(context, listen: false);
69 |
70 | var currentStatement = appData.astsList[widget.statementIndex];
71 |
72 | var graph = nodeInputFromJson(currentStatement.astGraph);
73 |
74 | WidgetsBinding.instance.addPostFrameCallback((_) {
75 | var error = currentStatement.errors[widget.index];
76 | if (showErrors && error != null && error != "") {
77 | utilsProvider.addConsoleMessage(error, 0);
78 | showErrors = false;
79 | }
80 | var outputMessage = currentStatement.outputMessages[widget.index];
81 | if (showOutput && outputMessage != null && outputMessage != "") {
82 | utilsProvider.addConsoleMessage(outputMessage, 1);
83 | showOutput = false;
84 | }
85 | });
86 |
87 | return DirectGraph(
88 | list: graph,
89 | cellWidth: 180.0,
90 | cellPadding: 14.0,
91 | contactEdgesDistance: 5.0,
92 | orientation: MatrixOrientation.Vertical,
93 | // pathBuilder: customEdgePathBuilder,
94 | builder: (ctx, node) {
95 | return Container(
96 | color:
97 | (currentStatement.visitedNode[widget.index] == int.parse(node.id)
98 | ? Colors.red
99 | : Colors.blue),
100 | child: Padding(
101 | padding: const EdgeInsets.all(10.0),
102 | child: ListView.builder(
103 | // controller: scrollController,
104 | itemCount:
105 | currentStatement.nodesData[widget.index][node.id].length,
106 | itemBuilder: (context, index) {
107 | if (index == 0) {
108 | return Center(
109 | child: Text(
110 | currentStatement.nodesData[widget.index][node.id]
111 | [index],
112 | style: text_style_graph_title));
113 | }
114 | return Text(
115 | "- " +
116 | currentStatement.nodesData[widget.index][node.id]
117 | [index],
118 | style: text_style_graph_text);
119 | },
120 | ),
121 | ),
122 | );
123 | },
124 | paintBuilder: (edge) {
125 | var p = Paint()
126 | ..color = Colors.blueGrey
127 | ..style = PaintingStyle.stroke
128 | ..strokeCap = StrokeCap.round
129 | ..strokeJoin = StrokeJoin.round
130 | ..strokeWidth = 2;
131 | return p;
132 | },
133 | );
134 | }
135 | }
136 |
--------------------------------------------------------------------------------
/InterpreterVisualizer/.mvn/wrapper/MavenWrapperDownloader.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2007-present the original author or authors.
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 | * https://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 | import java.net.*;
18 | import java.io.*;
19 | import java.nio.channels.*;
20 | import java.util.Properties;
21 |
22 | public class MavenWrapperDownloader {
23 |
24 | private static final String WRAPPER_VERSION = "0.5.6";
25 | /**
26 | * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided.
27 | */
28 | private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/"
29 | + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar";
30 |
31 | /**
32 | * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to
33 | * use instead of the default one.
34 | */
35 | private static final String MAVEN_WRAPPER_PROPERTIES_PATH =
36 | ".mvn/wrapper/maven-wrapper.properties";
37 |
38 | /**
39 | * Path where the maven-wrapper.jar will be saved to.
40 | */
41 | private static final String MAVEN_WRAPPER_JAR_PATH =
42 | ".mvn/wrapper/maven-wrapper.jar";
43 |
44 | /**
45 | * Name of the property which should be used to override the default download url for the wrapper.
46 | */
47 | private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl";
48 |
49 | public static void main(String args[]) {
50 | System.out.println("- Downloader started");
51 | File baseDirectory = new File(args[0]);
52 | System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath());
53 |
54 | // If the maven-wrapper.properties exists, read it and check if it contains a custom
55 | // wrapperUrl parameter.
56 | File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH);
57 | String url = DEFAULT_DOWNLOAD_URL;
58 | if (mavenWrapperPropertyFile.exists()) {
59 | FileInputStream mavenWrapperPropertyFileInputStream = null;
60 | try {
61 | mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile);
62 | Properties mavenWrapperProperties = new Properties();
63 | mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream);
64 | url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url);
65 | } catch (IOException e) {
66 | System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'");
67 | } finally {
68 | try {
69 | if (mavenWrapperPropertyFileInputStream != null) {
70 | mavenWrapperPropertyFileInputStream.close();
71 | }
72 | } catch (IOException e) {
73 | // Ignore ...
74 | }
75 | }
76 | }
77 | System.out.println("- Downloading from: " + url);
78 |
79 | File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH);
80 | if (!outputFile.getParentFile().exists()) {
81 | if (!outputFile.getParentFile().mkdirs()) {
82 | System.out.println(
83 | "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'");
84 | }
85 | }
86 | System.out.println("- Downloading to: " + outputFile.getAbsolutePath());
87 | try {
88 | downloadFileFromURL(url, outputFile);
89 | System.out.println("Done");
90 | System.exit(0);
91 | } catch (Throwable e) {
92 | System.out.println("- Error downloading");
93 | e.printStackTrace();
94 | System.exit(1);
95 | }
96 | }
97 |
98 | private static void downloadFileFromURL(String urlString, File destination) throws Exception {
99 | if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) {
100 | String username = System.getenv("MVNW_USERNAME");
101 | char[] password = System.getenv("MVNW_PASSWORD").toCharArray();
102 | Authenticator.setDefault(new Authenticator() {
103 | @Override
104 | protected PasswordAuthentication getPasswordAuthentication() {
105 | return new PasswordAuthentication(username, password);
106 | }
107 | });
108 | }
109 | URL website = new URL(urlString);
110 | ReadableByteChannel rbc;
111 | rbc = Channels.newChannel(website.openStream());
112 | FileOutputStream fos = new FileOutputStream(destination);
113 | fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
114 | fos.close();
115 | rbc.close();
116 | }
117 |
118 | }
119 |
--------------------------------------------------------------------------------
/lib/screens/parsing_ast_page.dart:
--------------------------------------------------------------------------------
1 | import 'dart:io';
2 | import 'dart:typed_data';
3 |
4 | import 'package:flutter/material.dart';
5 | import 'package:flutterdesktopapp/utils/app_data.dart';
6 | import 'package:flutterdesktopapp/utils/constants.dart';
7 | import 'package:flutterdesktopapp/utils/graphs_provider.dart';
8 | import 'package:graphite/core/matrix.dart';
9 | import 'package:graphite/graphite.dart';
10 | import 'package:path_provider/path_provider.dart';
11 | import 'package:provider/provider.dart';
12 | import 'package:screenshot/screenshot.dart';
13 |
14 | class ParsingASTPage extends StatefulWidget {
15 | @override
16 | _ParsingASTPageState createState() => _ParsingASTPageState();
17 | }
18 |
19 | class _ParsingASTPageState extends State {
20 |
21 | ScreenshotController screenshotController = ScreenshotController();
22 | int _counter = 0;
23 | Uint8List _imageFile;
24 |
25 | void _takeScreenshot(var context) {
26 | screenshotController.capture().then((Uint8List image) async {
27 | //Capture Done
28 | setState(() {
29 | _imageFile = image;
30 | print("hi");
31 | });
32 |
33 | Directory directory = await getDownloadsDirectory();
34 | String fileName = "Statement AST Tree" + ".png";
35 | var p = directory.path;
36 | var path = '$p';
37 | print(path);
38 | screenshotController.captureAndSave(path, fileName: fileName);
39 | final snackBar = SnackBar(
40 | content: Text('Graph is saved to $path'),
41 | );
42 | ;
43 | ScaffoldMessenger.of(context).showSnackBar(snackBar);
44 | }).catchError((onError) {
45 | print(onError);
46 | });
47 | }
48 |
49 | @override
50 | Widget build(BuildContext context) {
51 | return Container(
52 | child: Column(
53 | children: [
54 | Expanded(
55 | flex: 1,
56 | child: Row(
57 | mainAxisAlignment: MainAxisAlignment.center,
58 | children: [
59 | Text("Abstract Syntax Tree",
60 | style: text_style_phase_title),
61 | SizedBox(
62 | width: 10,
63 | ),
64 | IconButton(
65 | icon: Icon(Icons.camera_alt),
66 | onPressed: () => _takeScreenshot(context),
67 | )
68 | ],
69 | )),
70 | Expanded(
71 | flex: 10,
72 | child: SingleChildScrollView(
73 | scrollDirection: Axis.vertical,
74 | child: SingleChildScrollView(
75 | scrollDirection: Axis.horizontal,
76 | child: Screenshot(
77 | controller: screenshotController,
78 | child: SizedBox(
79 | width: 3000,
80 | height: 2000,
81 | child: Container(
82 | child: ParsingASTGraph(),
83 | ),
84 | ),
85 | ),
86 | ),
87 | ),
88 | ),
89 | ],
90 | ),
91 | );
92 | }
93 | }
94 |
95 | class ParsingASTGraph extends StatefulWidget {
96 | @override
97 | _ParsingASTGraphState createState() => _ParsingASTGraphState();
98 | }
99 |
100 | class _ParsingASTGraphState extends State {
101 | @override
102 | Widget build(BuildContext context) {
103 | var appData = Provider.of(context, listen: false);
104 | final graphProvider = Provider.of(context);
105 |
106 | int statementIndex = appData.visualizedStatementIndex;
107 | int graphIndex = graphProvider.visualizedGraphIndex;
108 |
109 | var currentStatement = appData.parsedStatementsList[statementIndex];
110 | var astGraphIndex = currentStatement.astGraphIndexSync[graphIndex];
111 |
112 | if (astGraphIndex == -1) return Container();
113 |
114 | var astGraph = currentStatement.astGraph;
115 |
116 | var graph = nodeInputFromJson(astGraph.graphs[astGraphIndex].toString());
117 |
118 | return DirectGraph(
119 | list: graph,
120 | cellWidth: 180.0,
121 | cellPadding: 14.0,
122 | contactEdgesDistance: 5.0,
123 | orientation: MatrixOrientation.Vertical,
124 | // pathBuilder: customEdgePathBuilder,
125 | builder: (ctx, node) {
126 | return Container(
127 | color: (astGraph.visitedNode[astGraphIndex] == int.parse(node.id)
128 | ? Colors.red
129 | : Colors.blue),
130 | child: Padding(
131 | padding: const EdgeInsets.all(10.0),
132 | child: ListView.builder(
133 | // controller: scrollController,
134 | itemCount: astGraph.nodesData[astGraphIndex][node.id].length,
135 | itemBuilder: (context, index) {
136 | if (index == 0) {
137 | return Center(
138 | child: Text(
139 | astGraph.nodesData[astGraphIndex][node.id][index],
140 | style: text_style_graph_title));
141 | }
142 | return Text(
143 | "- " + astGraph.nodesData[astGraphIndex][node.id][index],
144 | style: text_style_graph_text);
145 | },
146 | ),
147 | ),
148 | );
149 | },
150 | paintBuilder: (edge) {
151 | var p = Paint()
152 | ..color = Colors.blueGrey
153 | ..style = PaintingStyle.stroke
154 | ..strokeCap = StrokeCap.round
155 | ..strokeJoin = StrokeJoin.round
156 | ..strokeWidth = 2;
157 | return p;
158 | },
159 | );
160 | }
161 | }
162 |
--------------------------------------------------------------------------------
/InterpreterVisualizer/src/main/java/simpleinterpreter/SimpleInterpreter.java:
--------------------------------------------------------------------------------
1 | package simpleinterpreter;
2 |
3 | import org.json.JSONArray;
4 | import org.json.JSONObject;
5 |
6 | import java.util.List;
7 |
8 | public class SimpleInterpreter {
9 | private Scanner scanner;
10 | private Parser parser;
11 | private Interpreter interpreter;
12 |
13 | private boolean run = false;
14 | private boolean hadError = false;
15 | private boolean hadRuntimeError = false;
16 | private final String source;
17 |
18 | public SimpleInterpreter(String source) {
19 | this.source = source;
20 | run();
21 | }
22 |
23 | public void run() {
24 | if (run) return;
25 | run = true;
26 | scanner = new Scanner(source, this);
27 | scanner.scanTokens();
28 | List tokens = scanner.getTokens();
29 | parser = new Parser(tokens, this);
30 | parser.parse();
31 | List statements = parser.getStatements();
32 | if (hadError) return;
33 | interpreter = new Interpreter(this, parser.getStatmentsGraph());
34 | interpreter.interpret(statements);
35 |
36 | //Testing
37 | // System.out.println(parser.getStatmentsGraph().get(0).getAstGraph().getAstJSON().toString());
38 | // System.out.println(parser.getStatmentsGraph().get(0).getAstGraph().getNodesData().toString());
39 | // System.out.println(parser.getStatmentsGraph().get(0).getAstGraph().getVisitedNode().toString());
40 | // System.out.println(parser.getStatmentsGraph().get(0).getAstGraphIndexSync().toString());
41 |
42 | // System.out.println(interpreter.statmentsGraph.get(0).getAstGraph().;
43 | // System.out.println(interpreter.statmentsGraph.get(1).getAstGraph().getSymbolTableJSON().get(0).toString());
44 | // System.out.println(interpreter.statmentsGraph.get(2).getAstGraph().getSymbolTableJSON().get(0).toString());
45 | // System.out.println(interpreter.statmentsGraph.get(3).getAstGraph().getSymbolTableJSON().get(0).toString());
46 | }
47 |
48 | JSONObject getLexicalAnalysis() {
49 | run();
50 | JSONObject lexicalAnalysis = new JSONObject();
51 |
52 | List tokens = scanner.getTokens();
53 | JSONArray tokensJSON = new JSONArray();
54 | for (Token token : tokens) {
55 | tokensJSON.put(token.getTokenJSON());
56 | }
57 |
58 | JSONObject errorsJSON = scanner.getErrors();
59 |
60 | lexicalAnalysis.put("Tokens", tokensJSON);
61 | lexicalAnalysis.put("Errors", errorsJSON);
62 |
63 | return lexicalAnalysis;
64 | }
65 |
66 | JSONObject getSyntacticAnalysis() {
67 | run();
68 | JSONObject syntacticAnalysis = new JSONObject();
69 |
70 | List graph = parser.getStatmentsGraph();
71 | for (StatementGraph s : graph) {
72 | JSONObject statement = new JSONObject();
73 | statement.put("Graphs", s.getStatmentJSON());
74 | statement.put("Visited Nodes", s.getVisitedNode());
75 | statement.put("Nodes", s.getNodesData());
76 | statement.put("Consumed Tokens", s.getConsumedTokens());
77 | statement.put("Errors", s.getErrors());
78 | statement.put("AST Graph Index Sync", s.getAstGraphIndexSync());
79 |
80 | JSONObject ast = new JSONObject();
81 | ast.put("Graphs", s.getAstGraph().getAstJSON());
82 | ast.put("Visited Nodes", s.getAstGraph().getVisitedNode());
83 | ast.put("Nodes", s.getAstGraph().getNodesData());
84 | statement.put("AST", ast);
85 |
86 | syntacticAnalysis.append("Statements", statement);
87 | }
88 |
89 | return syntacticAnalysis;
90 | }
91 |
92 | JSONObject getSemanticAnalysis() {
93 | run();
94 | JSONObject semanticAnalysis = new JSONObject();
95 |
96 | if (hadError) return semanticAnalysis;
97 |
98 | List graph = interpreter.getStatmentsGraph();
99 | for (StatementGraph s : graph) {
100 | JSONObject statement = new JSONObject();
101 | statement.put("AST", s.getAstGraph().getInterpreterCompleteAST());
102 | statement.put("Visited Nodes", s.getAstGraph().getInterpreterVisitedNode());
103 | statement.put("Nodes", s.getAstGraph().getInterpreterNodesData());
104 | statement.put("Symbol Table Index Sync", s.getAstGraph().getSymbolTableIndexSync());
105 | statement.put("Symbol Table", s.getAstGraph().getSymbolTableJSON());
106 | statement.put("Errors", s.getAstGraph().getInterpreterRuntimeErrors());
107 | statement.put("Output Messages", s.getAstGraph().getInterpreterOutputMessages());
108 |
109 | semanticAnalysis.append("Statements", statement);
110 | }
111 |
112 | return semanticAnalysis;
113 | }
114 |
115 | void error(Token token, String message) {
116 | if (token.type == TokenType.EOF) {
117 | report(token.line, " at end", message);
118 | } else {
119 | report(token.line, " at '" + token.lexeme + "'", message);
120 | }
121 | }
122 |
123 | void error(int line, String message) {
124 | report(line, "", message);
125 | }
126 |
127 | void report(int line, String where,
128 | String message) {
129 | String output = "[line " + line + "] Error" + where + ": " + message;
130 | System.err.println(output);
131 | hadError = true;
132 | }
133 |
134 | void runtimeError(RuntimeError error) {
135 | String output = error.getMessage() + "\n[line " + error.token.line + "]";
136 | System.err.println(output);
137 | hadRuntimeError = true;
138 | }
139 | }
140 |
141 |
142 |
--------------------------------------------------------------------------------
/lib/screens/syntactic_and_statement_page.dart:
--------------------------------------------------------------------------------
1 | import 'dart:io';
2 | import 'dart:typed_data';
3 |
4 | import 'package:flutter/material.dart';
5 | import 'package:flutter/rendering.dart';
6 | import 'package:flutterdesktopapp/ui_elements/single_graph.dart';
7 | import 'package:flutterdesktopapp/utils/constants.dart';
8 | import 'package:flutterdesktopapp/utils/graphs_provider.dart';
9 | import 'package:path_provider/path_provider.dart';
10 | import 'package:provider/provider.dart';
11 | import 'package:screenshot/screenshot.dart';
12 |
13 | class SyntacticPage extends StatefulWidget {
14 | final int numberOfGraphs;
15 | final int visualizedStatementIndex;
16 |
17 | SyntacticPage(this.numberOfGraphs, this.visualizedStatementIndex);
18 |
19 | final statementPageKey = GlobalKey<_StatementPageState>();
20 |
21 | @override
22 | _SyntacticPageState createState() => _SyntacticPageState();
23 | }
24 |
25 | class _SyntacticPageState extends State {
26 | @override
27 | Widget build(BuildContext context) {
28 | return Container(
29 | child: StatementPage(
30 | key: widget.statementPageKey,
31 | numberOfGraphs: widget.numberOfGraphs,
32 | statementIndex: widget.visualizedStatementIndex),
33 | );
34 | }
35 | }
36 |
37 | class StatementPage extends StatefulWidget {
38 | final int numberOfGraphs;
39 | final int statementIndex;
40 |
41 | const StatementPage({Key key, this.numberOfGraphs, this.statementIndex})
42 | : super(key: key);
43 |
44 | @override
45 | _StatementPageState createState() => _StatementPageState();
46 | }
47 |
48 | class _StatementPageState extends State
49 | with TickerProviderStateMixin {
50 | AnimationController _animationController;
51 | double animationDuration;
52 | int durationOfSingleGraph;
53 | int totalDuration;
54 | int graphIndex = 0;
55 | Animation animation;
56 |
57 |
58 |
59 | @override
60 | void initState() {
61 | super.initState();
62 | durationOfSingleGraph = 900;
63 | totalDuration = widget.numberOfGraphs * durationOfSingleGraph;
64 | _animationController = AnimationController(
65 | vsync: this, duration: new Duration(milliseconds: totalDuration));
66 |
67 | _animationController.addListener(() {
68 | if (this.mounted) setState(() {});
69 | });
70 |
71 | animationDuration = durationOfSingleGraph / totalDuration;
72 | _animationController.forward();
73 | }
74 |
75 | @override
76 | void setState(VoidCallback fn) {
77 | var start = (animationDuration * graphIndex).toDouble();
78 | var end = start + animationDuration;
79 |
80 | start *= totalDuration;
81 | end *= totalDuration;
82 |
83 | if (_animationController.lastElapsedDuration != null &&
84 | _animationController.lastElapsedDuration.inMilliseconds.toDouble() >
85 | end) {
86 | graphIndex++;
87 | }
88 | // TODO: implement setState
89 | super.setState(fn);
90 | }
91 |
92 | @override
93 | void dispose() {
94 | print("Statement Disposed");
95 | _animationController.dispose();
96 | super.dispose();
97 | }
98 |
99 | ScreenshotController screenshotController = ScreenshotController();
100 | int _counter = 0;
101 | Uint8List _imageFile;
102 |
103 | void _takeScreenshot(var context) {
104 | screenshotController.capture().then((Uint8List image) async {
105 | //Capture Done
106 | setState(() {
107 | _imageFile = image;
108 | print("hi");
109 | });
110 |
111 | Directory directory = await getDownloadsDirectory();
112 | String fileName = "Parsing Tree Statement #" +
113 | widget.statementIndex.toString() +
114 | ".png";
115 | var p = directory.path;
116 | var path = '$p';
117 | print(path);
118 | screenshotController.captureAndSave(path, fileName: fileName);
119 | final snackBar = SnackBar(
120 | content: Text('Graph is saved to $path'),
121 | );
122 | ;
123 | ScaffoldMessenger.of(context).showSnackBar(snackBar);
124 | }).catchError((onError) {
125 | print(onError);
126 | });
127 | }
128 |
129 | @override
130 | Widget build(BuildContext context) {
131 | final graphProvider = Provider.of(context, listen: false);
132 | WidgetsBinding.instance.addPostFrameCallback((_) {
133 | graphProvider.visualizedGraphIndex = graphIndex;
134 | });
135 |
136 | return Container(
137 | child: Column(
138 | children: [
139 | Expanded(
140 | flex: 1,
141 | child: Row(
142 | mainAxisAlignment: MainAxisAlignment.center,
143 | children: [
144 | Text("Parsing Tree", style: text_style_phase_title),
145 | SizedBox(
146 | width: 10,
147 | ),
148 | IconButton(
149 | icon: Icon(Icons.camera_alt),
150 | onPressed: () => _takeScreenshot(context),
151 | )
152 | ],
153 | )),
154 | Expanded(
155 | flex: 10,
156 | child: SingleChildScrollView(
157 | scrollDirection: Axis.vertical,
158 | child: SingleChildScrollView(
159 | scrollDirection: Axis.horizontal,
160 | child: Screenshot(
161 | controller: screenshotController,
162 | child: SizedBox(
163 | height: 5000,
164 | width: 2000,
165 | child: Container(
166 | child: SingleGraph(graphIndex, widget.statementIndex,
167 | _animationController, animationDuration),
168 | ),
169 | ),
170 | ),
171 | ),
172 | ),
173 | ),
174 | ],
175 | ),
176 | );
177 | }
178 | }
179 |
--------------------------------------------------------------------------------
/lib/screens/semantic_page.dart:
--------------------------------------------------------------------------------
1 | import 'dart:io';
2 | import 'dart:typed_data';
3 |
4 | import 'package:flutter/material.dart';
5 | import 'package:flutter/rendering.dart';
6 | import 'package:flutterdesktopapp/utils/constants.dart';
7 | import 'package:flutterdesktopapp/utils/graphs_provider.dart';
8 | import 'package:path_provider/path_provider.dart';
9 | import 'package:provider/provider.dart';
10 | import 'package:screenshot/screenshot.dart';
11 |
12 | import 'ast_graph.dart';
13 |
14 | class SemanticPage extends StatefulWidget {
15 | final int numberOfSteps;
16 | final int visualizedStatementIndex;
17 |
18 | SemanticPage(this.numberOfSteps, this.visualizedStatementIndex);
19 |
20 | final semanticStatementPageKey = GlobalKey<_SemanticStatementPageState>();
21 |
22 | @override
23 | _SemanticPageState createState() => _SemanticPageState();
24 | }
25 |
26 | class _SemanticPageState extends State {
27 | @override
28 | Widget build(BuildContext context) {
29 | return Container(
30 | child: SemanticStatementPage(
31 | key: widget.semanticStatementPageKey,
32 | numberOfSteps: widget.numberOfSteps,
33 | statementIndex: widget.visualizedStatementIndex),
34 | );
35 | }
36 | }
37 |
38 | class SemanticStatementPage extends StatefulWidget {
39 | final int numberOfSteps;
40 | final int statementIndex;
41 |
42 | const SemanticStatementPage(
43 | {Key key, this.numberOfSteps, this.statementIndex})
44 | : super(key: key);
45 |
46 | @override
47 | _SemanticStatementPageState createState() => _SemanticStatementPageState();
48 | }
49 |
50 | class _SemanticStatementPageState extends State
51 | with TickerProviderStateMixin {
52 | AnimationController _animationController;
53 | double animationDuration;
54 | int durationOfSingleStep;
55 | int totalDuration;
56 | int stepIndex = 0;
57 | Animation animation;
58 |
59 | @override
60 | void initState() {
61 | super.initState();
62 | durationOfSingleStep = 900;
63 | totalDuration = widget.numberOfSteps * durationOfSingleStep;
64 | _animationController = AnimationController(
65 | vsync: this, duration: new Duration(milliseconds: totalDuration));
66 |
67 | _animationController.addListener(() {
68 | if (this.mounted) setState(() {});
69 | });
70 |
71 | animationDuration = durationOfSingleStep / totalDuration;
72 | _animationController.forward();
73 | }
74 |
75 | @override
76 | void setState(VoidCallback fn) {
77 | var start = (animationDuration * stepIndex).toDouble();
78 | var end = start + animationDuration;
79 |
80 | start *= totalDuration;
81 | end *= totalDuration;
82 |
83 | if (_animationController.lastElapsedDuration != null &&
84 | _animationController.lastElapsedDuration.inMilliseconds.toDouble() >
85 | end) {
86 | stepIndex++;
87 | }
88 | // TODO: implement setState
89 | super.setState(fn);
90 | }
91 |
92 | @override
93 | void dispose() {
94 | print("Statement AST Disposed");
95 | _animationController.dispose();
96 | super.dispose();
97 | }
98 |
99 |
100 | ScreenshotController screenshotController = ScreenshotController();
101 | int _counter = 0;
102 | Uint8List _imageFile;
103 |
104 | void _takeScreenshot(var context) {
105 | screenshotController.capture().then((Uint8List image) async {
106 | //Capture Done
107 | setState(() {
108 | _imageFile = image;
109 | print("hi");
110 | });
111 |
112 | Directory directory = await getDownloadsDirectory();
113 | String fileName = "AST Tree Statement #" +
114 | widget.statementIndex.toString() +
115 | ".png";
116 | var p = directory.path;
117 | var path = '$p';
118 | print(path);
119 | screenshotController.captureAndSave(path, fileName: fileName);
120 | final snackBar = SnackBar(
121 | content: Text('Graph is saved to $path'),
122 | );
123 | ;
124 | ScaffoldMessenger.of(context).showSnackBar(snackBar);
125 | }).catchError((onError) {
126 | print(onError);
127 | });
128 | }
129 |
130 | @override
131 | Widget build(BuildContext context) {
132 | final graphProvider = Provider.of(context, listen: false);
133 | WidgetsBinding.instance.addPostFrameCallback((_) {
134 | graphProvider.visualizedStatementIndex = widget.statementIndex;
135 | graphProvider.visualizedStepIndex = stepIndex;
136 | });
137 |
138 | return Container(
139 | child: Column(
140 | children: [
141 | Expanded(
142 | flex: 1,
143 | child: Row(
144 | mainAxisAlignment: MainAxisAlignment.center,
145 | children: [
146 | Text("Abstract Syntax Tree",
147 | style: text_style_phase_title),
148 | IconButton(
149 | icon: Icon(Icons.camera_alt),
150 | onPressed: () => _takeScreenshot(context),
151 | )
152 | ],
153 | )),
154 | Expanded(
155 | flex: 10,
156 | child: SingleChildScrollView(
157 | scrollDirection: Axis.vertical,
158 | child: SingleChildScrollView(
159 | scrollDirection: Axis.horizontal,
160 | child: Screenshot(
161 | controller: screenshotController,
162 | child: SizedBox(
163 | height: 3000,
164 | width: 2000,
165 | child: Container(
166 | child: ASTGraph(stepIndex, widget.statementIndex,
167 | _animationController, animationDuration),
168 | ),
169 | ),
170 | ),
171 | ),
172 | ),
173 | ),
174 | ],
175 | ),
176 | );
177 | }
178 | }
179 |
--------------------------------------------------------------------------------
/lib/ui_elements/single_graph.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutterdesktopapp/utils/app_data.dart';
3 | import 'package:flutterdesktopapp/utils/constants.dart';
4 | import 'package:flutterdesktopapp/utils/utilities_provider.dart';
5 | import 'package:graphite/core/matrix.dart';
6 | import 'package:graphite/graphite.dart';
7 | import 'package:provider/provider.dart';
8 |
9 | class SingleGraph extends StatefulWidget {
10 | final int statementIndex;
11 | final int index;
12 | final double duration;
13 | final AnimationController animationController;
14 |
15 | SingleGraph(
16 | this.index, this.statementIndex, this.animationController, this.duration);
17 |
18 | @override
19 | _SingleGraphState createState() => _SingleGraphState();
20 | }
21 |
22 | class _SingleGraphState extends State {
23 | Animation animation;
24 | Animation animationColor;
25 | double start;
26 | double end;
27 | var showErrors = true;
28 |
29 | @override
30 | void initState() {
31 | print(widget.index.toString() + " signing in");
32 | super.initState();
33 | start = (widget.duration * widget.index).toDouble();
34 | end = start + widget.duration;
35 | print("START $start , end $end");
36 |
37 | animation = Tween(
38 | begin: 0.0,
39 | end: 1.0,
40 | ).animate(
41 | CurvedAnimation(
42 | parent: widget.animationController,
43 | curve: Interval(
44 | start,
45 | end,
46 | curve: Curves.easeInOutCirc,
47 | ),
48 | ),
49 | );
50 |
51 | animationColor = ColorTween(
52 | begin: Colors.white,
53 | end: Colors.black87,
54 | ).animate(
55 | CurvedAnimation(
56 | parent: widget.animationController,
57 | curve: Interval(
58 | start,
59 | end,
60 | curve: Curves.easeInOutCirc,
61 | ),
62 | ),
63 | );
64 |
65 | widget.animationController.addListener(() {
66 | if (this.mounted) setState(() {});
67 | });
68 | }
69 |
70 | @override
71 | void dispose() {
72 | print("Graph Disposed");
73 | // TODO: implement dispose
74 | super.dispose();
75 | }
76 |
77 | @override
78 | Widget build(BuildContext context) {
79 | // ScrollController scrollController = ScrollController();
80 | // var scrollToBottom = (){
81 | // scrollController.jumpTo(scrollController.position.maxScrollExtent);
82 | // };
83 |
84 | var appData = Provider.of(context);
85 | var currentStatement = appData.parsedStatementsList[widget.statementIndex];
86 | var graph =
87 | nodeInputFromJson(currentStatement.graphs[widget.index].toString());
88 |
89 | final utilsProvider =
90 | Provider.of(context, listen: false);
91 |
92 | WidgetsBinding.instance.addPostFrameCallback((_) {
93 | // scrollToBottom();
94 |
95 | var currentErrors = currentStatement.errors[widget.index];
96 | if (showErrors && currentErrors != null && currentErrors.isNotEmpty) {
97 | for (var error in currentErrors) {
98 | utilsProvider.addConsoleMessage(error, 0);
99 | }
100 | showErrors = false;
101 | }
102 |
103 | var consumedTokens = currentStatement.consumedTokens[widget.index];
104 | if (consumedTokens != null && consumedTokens.isNotEmpty) {
105 | for (int token in consumedTokens) {
106 | var tokenIndex = appData.tokensIndices[token];
107 | var tokenGoalColor = appData.tokensColors[tokenIndex];
108 | Color t = tokenGoalColor;
109 | Color x = animationColor.value;
110 | utilsProvider.richTextList[tokenIndex][1] = t.withOpacity(x.opacity);
111 | }
112 | var temp1 = List.from(utilsProvider.richTextList);
113 | utilsProvider.richTextList = temp1;
114 | }
115 | });
116 |
117 | return Opacity(
118 | opacity: animation.value,
119 | child: DirectGraph(
120 | list: graph,
121 | cellWidth: 180.0,
122 | cellPadding: 14.0,
123 | contactEdgesDistance: 5.0,
124 | orientation: MatrixOrientation.Vertical,
125 | // pathBuilder: customEdgePathBuilder,
126 | builder: (ctx, node) {
127 | return Container(
128 | color: (currentStatement.visitedNode[widget.index] ==
129 | int.parse(node.id)
130 | ? Colors.red
131 | : Colors.blue),
132 | child: Padding(
133 | padding: const EdgeInsets.all(10.0),
134 | child: ListView.builder(
135 | // controller: scrollController,
136 | itemCount:
137 | currentStatement.nodesData[widget.index][node.id].length,
138 | itemBuilder: (context, index) {
139 | if (index == 0) {
140 | return Center(
141 | child: Text(
142 | currentStatement.nodesData[widget.index][node.id]
143 | [index],
144 | style: text_style_graph_title));
145 | }
146 | return Text(
147 | "- " +
148 | currentStatement.nodesData[widget.index][node.id]
149 | [index],
150 | style: text_style_graph_text);
151 | },
152 | ),
153 | ),
154 | );
155 | },
156 | paintBuilder: (edge) {
157 | var p = Paint()
158 | ..color = Colors.blueGrey
159 | ..style = PaintingStyle.stroke
160 | ..strokeCap = StrokeCap.round
161 | ..strokeJoin = StrokeJoin.round
162 | ..strokeWidth = 2;
163 | return p;
164 | },
165 | ),
166 | );
167 | }
168 |
169 | Path customEdgePathBuilder(List> points) {
170 | var path = Path();
171 | path.moveTo(points[0][0], points[0][1]);
172 | points.sublist(1).forEach((p) {
173 | path.lineTo(p[0], p[1]);
174 | });
175 | return path;
176 | }
177 | }
178 |
--------------------------------------------------------------------------------
/InterpreterVisualizer/src/main/java/simpleinterpreter/StatementGraph.java:
--------------------------------------------------------------------------------
1 | package simpleinterpreter;
2 |
3 | import org.json.JSONArray;
4 | import org.json.JSONObject;
5 |
6 | import java.util.ArrayList;
7 | import java.util.HashMap;
8 | import java.util.List;
9 | import java.util.Map;
10 |
11 | public class StatementGraph {
12 |
13 | public AST getAstGraph() {
14 | return astGraph;
15 | }
16 |
17 | private final AST astGraph;
18 |
19 | //same size
20 | private final List statmentJSON;
21 | private final JSONArray visitedNode;
22 |
23 | public JSONArray getAstGraphIndexSync() {
24 | return astGraphIndexSync;
25 | }
26 |
27 | private final JSONArray astGraphIndexSync;
28 |
29 | private final List nodesData;
30 |
31 |
32 | private final String ID = "\"id\"";
33 | private final String NEXT = "\"next\"";
34 |
35 | private final Map> consumedTokens;
36 | private final JSONArray errors;
37 |
38 |
39 | //helper map
40 | private final Map nodeInIndex;
41 |
42 | StatementGraph() {
43 | astGraph = new AST();
44 | statmentJSON = new ArrayList<>();
45 | nodeInIndex = new HashMap<>();
46 | consumedTokens = new HashMap<>();
47 | visitedNode = new JSONArray();
48 | astGraphIndexSync = new JSONArray();
49 | errors = new JSONArray();
50 | nodesData = new ArrayList<>();
51 | }
52 |
53 | void addASTNode(int parsingNodeIndex, int astNodeindex, List data, List neighbours) {
54 | astGraph.addNewNode(astNodeindex, data, neighbours);
55 | visitNode(parsingNodeIndex, "");
56 | }
57 |
58 | void addNodeData(int index, String data) {
59 | //Data
60 | JSONObject lastDataJSONObject = new JSONObject(getLastJSONObject().toString());
61 | if (data != "") {
62 | lastDataJSONObject.append(Integer.toString(index), data);
63 | }
64 | nodesData.add(lastDataJSONObject);
65 | }
66 |
67 | void addNewNode(int index, String data) {
68 | nodeInIndex.put(index, getLastJSONArray().length());
69 |
70 | addNodeData(index, data);
71 |
72 | JSONArray lastJSONArray = new JSONArray(getLastJSONArray().toString());
73 |
74 | int lastNode = getLastVisitedNodeIndex(); //from
75 |
76 | visitedNode.put(index);
77 | if (lastNode != -1) {
78 | int indexOfNodeInJSON = nodeInIndex.get(lastNode);
79 | lastJSONArray.getJSONObject(indexOfNodeInJSON).append(NEXT, toStringWithDoubleQuotes(index));
80 | }
81 |
82 | JSONObject currentNode = new JSONObject();
83 | currentNode.put(ID, toStringWithDoubleQuotes(index));
84 | currentNode.put(NEXT, new JSONArray());
85 |
86 | lastJSONArray.put(currentNode);
87 | statmentJSON.add(lastJSONArray);
88 | astGraphIndexSync.put(astGraph.getASTsSize() - 1);
89 | }
90 |
91 | void visitNode(int index, String data) {
92 | visitedNode.put(index);
93 |
94 | addNodeData(index, data);
95 |
96 | // keep the lists consistent
97 | JSONArray last = getLastJSONArray();
98 | statmentJSON.add(last);
99 | astGraphIndexSync.put(astGraph.getASTsSize() - 1);
100 | }
101 |
102 | void consumeToken(int tokenIndex) {
103 | int index = statmentJSON.size() - 1;
104 | if (consumedTokens.get(index) == null) {
105 | consumedTokens.put(index, new ArrayList<>());
106 | }
107 | consumedTokens.get(statmentJSON.size() - 1).add(tokenIndex);
108 | }
109 |
110 | void reportSyntaxError(String message) {
111 | int index = statmentJSON.size() - 1;
112 | JSONObject error = new JSONObject();
113 | error.put(Integer.toString(index), message);
114 | errors.put(error);
115 | }
116 |
117 |
118 | JSONArray getLastJSONArray() {
119 | int size = statmentJSON.size();
120 | if (size == 0)
121 | return new JSONArray();
122 | return statmentJSON.get(size - 1);
123 | }
124 |
125 | JSONObject getLastJSONObject() {
126 | int size = nodesData.size();
127 | if (size == 0)
128 | return new JSONObject();
129 | return nodesData.get(size - 1);
130 | }
131 |
132 | int getLastVisitedNodeIndex() {
133 | int size = visitedNode.length();
134 | if (size == 0)
135 | return -1;
136 | return visitedNode.getInt(size - 1);
137 |
138 | }
139 |
140 | public List getStatmentJSON() {
141 | return statmentJSON;
142 | }
143 |
144 |
145 | String toStringWithDoubleQuotes(int index) {
146 | return "\"" + index + "\"";
147 | }
148 |
149 |
150 | // public List getVisitedNode() {
151 | // return visitedNode;
152 | // }
153 | //
154 | // public List getNodesData() {
155 | // return nodesData;
156 | // }
157 | //
158 | // public Map> getConsumedTokens() {
159 | // return consumedTokens;
160 | // }
161 | //
162 | // public List getErrors() {
163 | // return errors;
164 | // }
165 | //
166 | // public Map getNodeInIndex() {
167 | // return nodeInIndex;
168 | // }
169 |
170 |
171 | public JSONArray getVisitedNode() {
172 | return visitedNode;
173 | }
174 |
175 | public JSONArray getNodesData() {
176 | JSONArray nodesDataJSONArray = new JSONArray();
177 | for (JSONObject jsonObject : nodesData) {
178 | nodesDataJSONArray.put(jsonObject);
179 | }
180 | return nodesDataJSONArray;
181 | }
182 |
183 | public JSONArray getConsumedTokens() {
184 | JSONArray consumedTokensJSON = new JSONArray();
185 | for (Map.Entry> entry : consumedTokens.entrySet()) {
186 | JSONObject list = new JSONObject();
187 | list.put(Integer.toString(entry.getKey()), entry.getValue());
188 | consumedTokensJSON.put(list);
189 | }
190 | return consumedTokensJSON;
191 | }
192 |
193 | public JSONArray getErrors() {
194 | return errors;
195 | }
196 |
197 | }
198 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Interpreter Visualizer
2 | Believing in visualization as a very interactive method to help enhance and improve education, We have developed this very new desktop application to help and inspire Compiler Design learners so that they get a better experience and understand it well. We also want to inspire other programmers around the world to help create more educational applications or improve the already existing ones.
3 |
4 |
5 | ## Table of content:
6 | 1. [Important Note](#note)
7 | 2. [Idea of the project](#idea)
8 | 3. [Lox Language](#lox)
9 | 4. [How to use](#install)
10 | 5. [Examples](#ex)
11 | 6. [Depedencies](#Depend)
12 | 7. [Contribution](#con)
13 |
14 |
15 | ### Important Note
16 | When talking about the interpreter if we mention the front-end part and the back-end part we mean by the front-end the lexical analysis, the syntactic analysis and the semantic analysis(The part of the interperter we have made it possible to visualize). And if we are talking about the project as a code we mean by the front-end the Flutter project and the back-end is the Java Spring project. So, these terms are similar but their meaning is way too different so don't mix them up.
17 |
18 |
19 | ### Idea of the project
20 |
21 | This application simply visualizes the front-end part of interpreters or compilers and that includes Lexical Analysis, Syntactic Analysis and Semantic analysis.
22 | By using this application you will be able to:
23 | 1- Visualize any part of your code in the front-end part of an interpreter or a compiler.
24 | 2- Try and error your understanding of the compiler theory subject.
25 | 3- Know where your code can fail in the front-end part.
26 | 4- Use it as a professor in the university or in the lab class to help you deliver your lectures the best way possible.
27 |
28 |
29 | ### Lox Language
30 |
31 | Lox is the programming laguage used in our application to be visualized. It is an educational language created by [Robert Nystrom](https://github.com/munificent) in his famous book [Crafting interpreters](https://craftinginterpreters.com/contents.html) which we have used to help us create its interpreter. The reason we chose this language is that it is very simple, a C-style language and its grammar is very easy to read through. But our project does not only visualize Lox, **it can actually visaulize any programming language**, but you will need to change the back-end side (The Java Spring Project), but the front-end(The Flutter Project) will just work the same.
32 | Have a look at the language simple grammar [here](LoxGrammar). **We have not implemented yet all the grammar included in the crafting interpreters book**.
33 |
34 | You may also check some examples and learn more about the syntax of the language from [here](https://craftinginterpreters.com/the-lox-language.html). But notice that we have only implemented what you will find in the [grammar file](LoxGrammar), some parts of the language like the OOP or the functions are not implemented yet. So, if you doubt any part of the language to use just check the [grammar file](LoxGrammar).
35 |
36 |
37 | ### How to use
38 |
39 | This application consists of two separate parts the desktop/web front-end part which is written in Flutter and the back-end side written in Java Spring. The back-end side is found in the folder [**InterpreterVisualizer**](https://github.com/OsamaMaani/Interpreter-Visualizer/tree/master/InterpreterVisualizer).
40 |
41 | Make sure to:
42 |
43 | 1- Use the same port and IP address for both the back-end side and the fron-end side and you can modify that in the [properties file](https://github.com/OsamaMaani/Interpreter-Visualizer/blob/master/InterpreterVisualizer/src/main/resources/application.properties) in the back-end project and you can modify that in the [networking file](https://github.com/OsamaMaani/Interpreter-Visualizer/blob/master/lib/services/networking.dart) in the Flutter project.
44 |
45 | 2- Modify the graphite library so that it works properly for the project. You will head to the external libraries in the flutter project and then you will find graphite library folder, you will then open **graphite_edges.dart** and then go to **_GraphiteEdgesState** class and then head to **InteractiveViewer** widget and add **scaleEnabled: false**. This attribute will make sure that the zooming in the screen is off and there will not be unexpected functionalities caused by the zooming.
46 |
47 | .
48 |
49 |
50 | ### Examples
51 |
52 |
53 | **Example One**
54 |
55 | In this example you can see how the tokenization process goes on token by token with each one gets a unique color according to its type.
56 | 
57 |
58 | **Example Two**
59 |
60 | In this example you can see here how a character can't be recognized if it is not a part of the language like the **#** symbol in our case.
61 | Also, an immediate message in the **console** appears to indicate that error.
62 | 
63 |
64 | **Example Three**
65 |
66 | In this example you can see the panel is divided into two smaller panels, the left one to show how the interpreter recursively search the grammar to find the specific grammar of the expression creating **the Parsing Tree** and on the right you can see the **Abstract Syntax Tree**(AST).
67 | You can also see a camera icon beside the title in each panel and if it is clicked it will immediately generate a screenshot to either the parsing tree or the AST to the moment you clicked.
68 | 
69 |
70 | **Example Four**
71 |
72 | In this example you can see the semantic analysis visualization including the symbol table in the bottom of the screen.
73 | 
74 |
75 | **Example Five**
76 | Here, in this example you can see how the semantic analysis phase can produce output in the **console** using print expression.
77 | 
78 |
79 |
80 | ### Dependencies
81 |
82 | The Dependencies used in the Flutter Desktop/Web app.
83 | 1. [HTTP package](https://pub.dev/packages/http)
84 | 2. [Provider Package](https://pub.dev/packages/provider)
85 | 3. [path_provider](https://pub.dev/packages/path_provider)
86 | 4. [graphite](https://pub.dev/packages/graphite)
87 | 5. [Flutter Progress Hud](https://pub.dev/packages/flutter_progress_hud)
88 | 6. [screenshot](https://pub.dev/packages/screenshot)
89 |
90 | The Dependencies used in the Java Spring back-end app.
91 |
92 | 1- [JSON](https://mvnrepository.com/artifact/org.json/json/20090211)
93 |
94 |
95 | ## Contribution
96 |
97 | Follow the guides mentioned in the [CONTRIBUTING.md](contribution.md).
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
--------------------------------------------------------------------------------
/InterpreterVisualizer/mvnw.cmd:
--------------------------------------------------------------------------------
1 | @REM ----------------------------------------------------------------------------
2 | @REM Licensed to the Apache Software Foundation (ASF) under one
3 | @REM or more contributor license agreements. See the NOTICE file
4 | @REM distributed with this work for additional information
5 | @REM regarding copyright ownership. The ASF licenses this file
6 | @REM to you under the Apache License, Version 2.0 (the
7 | @REM "License"); you may not use this file except in compliance
8 | @REM with the License. You may obtain a copy of the License at
9 | @REM
10 | @REM https://www.apache.org/licenses/LICENSE-2.0
11 | @REM
12 | @REM Unless required by applicable law or agreed to in writing,
13 | @REM software distributed under the License is distributed on an
14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | @REM KIND, either express or implied. See the License for the
16 | @REM specific language governing permissions and limitations
17 | @REM under the License.
18 | @REM ----------------------------------------------------------------------------
19 |
20 | @REM ----------------------------------------------------------------------------
21 | @REM Maven Start Up Batch script
22 | @REM
23 | @REM Required ENV vars:
24 | @REM JAVA_HOME - location of a JDK home dir
25 | @REM
26 | @REM Optional ENV vars
27 | @REM M2_HOME - location of maven2's installed home dir
28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
31 | @REM e.g. to debug Maven itself, use
32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
34 | @REM ----------------------------------------------------------------------------
35 |
36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
37 | @echo off
38 | @REM set title of command window
39 | title %0
40 | @REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
41 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
42 |
43 | @REM set %HOME% to equivalent of $HOME
44 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
45 |
46 | @REM Execute a user defined script before this one
47 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
48 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending
49 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
50 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
51 | :skipRcPre
52 |
53 | @setlocal
54 |
55 | set ERROR_CODE=0
56 |
57 | @REM To isolate internal variables from possible post scripts, we use another setlocal
58 | @setlocal
59 |
60 | @REM ==== START VALIDATION ====
61 | if not "%JAVA_HOME%" == "" goto OkJHome
62 |
63 | echo.
64 | echo Error: JAVA_HOME not found in your environment. >&2
65 | echo Please set the JAVA_HOME variable in your environment to match the >&2
66 | echo location of your Java installation. >&2
67 | echo.
68 | goto error
69 |
70 | :OkJHome
71 | if exist "%JAVA_HOME%\bin\java.exe" goto init
72 |
73 | echo.
74 | echo Error: JAVA_HOME is set to an invalid directory. >&2
75 | echo JAVA_HOME = "%JAVA_HOME%" >&2
76 | echo Please set the JAVA_HOME variable in your environment to match the >&2
77 | echo location of your Java installation. >&2
78 | echo.
79 | goto error
80 |
81 | @REM ==== END VALIDATION ====
82 |
83 | :init
84 |
85 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
86 | @REM Fallback to current working directory if not found.
87 |
88 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
89 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
90 |
91 | set EXEC_DIR=%CD%
92 | set WDIR=%EXEC_DIR%
93 | :findBaseDir
94 | IF EXIST "%WDIR%"\.mvn goto baseDirFound
95 | cd ..
96 | IF "%WDIR%"=="%CD%" goto baseDirNotFound
97 | set WDIR=%CD%
98 | goto findBaseDir
99 |
100 | :baseDirFound
101 | set MAVEN_PROJECTBASEDIR=%WDIR%
102 | cd "%EXEC_DIR%"
103 | goto endDetectBaseDir
104 |
105 | :baseDirNotFound
106 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
107 | cd "%EXEC_DIR%"
108 |
109 | :endDetectBaseDir
110 |
111 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
112 |
113 | @setlocal EnableExtensions EnableDelayedExpansion
114 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
115 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
116 |
117 | :endReadAdditionalConfig
118 |
119 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
120 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
121 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
122 |
123 | set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
124 |
125 | FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
126 | IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
127 | )
128 |
129 | @REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
130 | @REM This allows using the maven wrapper in projects that prohibit checking in binary data.
131 | if exist %WRAPPER_JAR% (
132 | if "%MVNW_VERBOSE%" == "true" (
133 | echo Found %WRAPPER_JAR%
134 | )
135 | ) else (
136 | if not "%MVNW_REPOURL%" == "" (
137 | SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
138 | )
139 | if "%MVNW_VERBOSE%" == "true" (
140 | echo Couldn't find %WRAPPER_JAR%, downloading it ...
141 | echo Downloading from: %DOWNLOAD_URL%
142 | )
143 |
144 | powershell -Command "&{"^
145 | "$webclient = new-object System.Net.WebClient;"^
146 | "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
147 | "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
148 | "}"^
149 | "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^
150 | "}"
151 | if "%MVNW_VERBOSE%" == "true" (
152 | echo Finished downloading %WRAPPER_JAR%
153 | )
154 | )
155 | @REM End of extension
156 |
157 | @REM Provide a "standardized" way to retrieve the CLI args that will
158 | @REM work with both Windows and non-Windows executions.
159 | set MAVEN_CMD_LINE_ARGS=%*
160 |
161 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
162 | if ERRORLEVEL 1 goto error
163 | goto end
164 |
165 | :error
166 | set ERROR_CODE=1
167 |
168 | :end
169 | @endlocal & set ERROR_CODE=%ERROR_CODE%
170 |
171 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
172 | @REM check for post script, once with legacy .bat ending and once with .cmd ending
173 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
174 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
175 | :skipRcPost
176 |
177 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
178 | if "%MAVEN_BATCH_PAUSE%" == "on" pause
179 |
180 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
181 |
182 | exit /B %ERROR_CODE%
183 |
--------------------------------------------------------------------------------
/InterpreterVisualizer/src/main/java/simpleinterpreter/Scanner.java:
--------------------------------------------------------------------------------
1 | package simpleinterpreter;
2 |
3 | import org.json.JSONObject;
4 |
5 | import java.util.ArrayList;
6 | import java.util.HashMap;
7 | import java.util.List;
8 | import java.util.Map;
9 |
10 | import static simpleinterpreter.TokenType.*;
11 |
12 | class Scanner {
13 | private static final Map keywords;
14 |
15 | static {
16 | keywords = new HashMap<>();
17 | keywords.put("and", AND);
18 | keywords.put("class", CLASS);
19 | keywords.put("else", ELSE);
20 | keywords.put("false", FALSE);
21 | keywords.put("for", FOR);
22 | keywords.put("fun", FUN);
23 | keywords.put("if", IF);
24 | keywords.put("nil", NIL);
25 | keywords.put("or", OR);
26 | keywords.put("print", PRINT);
27 | keywords.put("return", RETURN);
28 | keywords.put("super", SUPER);
29 | keywords.put("this", THIS);
30 | keywords.put("true", TRUE);
31 | keywords.put("var", VAR);
32 | keywords.put("while", WHILE);
33 | }
34 |
35 | private final String source;
36 |
37 | private final List tokens = new ArrayList<>();
38 | private final JSONObject errors = new JSONObject();
39 |
40 | private int start = 0;
41 | private int current = 0;
42 | private int line = 1;
43 |
44 |
45 | SimpleInterpreter simpleInterpreter;
46 |
47 | Scanner(String source, SimpleInterpreter simpleInterpreter) {
48 | this.source = source;
49 | this.simpleInterpreter = simpleInterpreter;
50 | }
51 |
52 | public List getTokens() {
53 | return tokens;
54 | }
55 |
56 | public JSONObject getErrors() {
57 | return errors;
58 | }
59 |
60 | void scanTokens() {
61 | while (!isAtEnd()) {
62 | start = current;
63 | scanToken();
64 | }
65 |
66 | tokens.add(new Token(EOF, "", null, line, current, current));
67 | }
68 |
69 | private void scanToken() {
70 | char c = advance();
71 | switch (c) {
72 | case '(':
73 | addToken(LEFT_PAREN);
74 | break;
75 | case ')':
76 | addToken(RIGHT_PAREN);
77 | break;
78 | case '{':
79 | addToken(LEFT_BRACE);
80 | break;
81 | case '}':
82 | addToken(RIGHT_BRACE);
83 | break;
84 | case ',':
85 | addToken(COMMA);
86 | break;
87 | case '.':
88 | addToken(DOT);
89 | break;
90 | case '-':
91 | addToken(MINUS);
92 | break;
93 | case '+':
94 | addToken(PLUS);
95 | break;
96 | case ';':
97 | addToken(SEMICOLON);
98 | break;
99 | case '*':
100 | addToken(STAR);
101 | break;
102 |
103 | case '!':
104 | addToken(match('=') ? BANG_EQUAL : BANG);
105 | break;
106 | case '=':
107 | addToken(match('=') ? EQUAL_EQUAL : EQUAL);
108 | break;
109 | case '<':
110 | addToken(match('=') ? LESS_EQUAL : LESS);
111 | break;
112 | case '>':
113 | addToken(match('=') ? GREATER_EQUAL : GREATER);
114 | break;
115 |
116 | case '/':
117 | if (match('/')) {
118 | while (peek() != '\n' && !isAtEnd()) advance();
119 | } else {
120 | addToken(SLASH);
121 | }
122 | break;
123 |
124 |
125 | case ' ':
126 | case '\r':
127 | case '\t':
128 | break;
129 |
130 | case '\n':
131 | line++;
132 | break;
133 |
134 |
135 | case '"':
136 | string();
137 | break;
138 |
139 |
140 | default:
141 | if (isDigit(c)) {
142 | number();
143 | } else if (isAlpha(c)) {
144 | identifier();
145 | } else {
146 | errors.append(Integer.toString((tokens.size())), "[line " + line + "] Error: Unexpected character.");
147 | // errors.put(new JSONObject().put(Integer.toString((tokens.size() + 1)), "[line " + line + "] Error: Unexpected character."));
148 | simpleInterpreter.error(line, "Unexpected character.");
149 | }
150 | break;
151 | }
152 | }
153 |
154 | private void identifier() {
155 | while (isAlphaNumeric(peek())) advance();
156 |
157 | String text = source.substring(start, current);
158 | TokenType type = keywords.get(text);
159 | if (type == null) type = IDENTIFIER;
160 | addToken(type);
161 | }
162 |
163 | private void number() {
164 | while (isDigit(peek())) advance();
165 |
166 |
167 | if (peek() == '.' && isDigit(peekNext())) {
168 |
169 | advance();
170 |
171 | while (isDigit(peek())) advance();
172 | }
173 |
174 | addToken(NUMBER,
175 | Double.parseDouble(source.substring(start, current)));
176 | }
177 |
178 |
179 | private void string() {
180 | while (peek() != '"' && !isAtEnd()) {
181 | if (peek() == '\n') line++;
182 | advance();
183 | }
184 |
185 | if (isAtEnd()) {
186 | errors.append(Integer.toString((tokens.size())), "[line " + line + "] Error: Unterminated string.");
187 | // errors.put(new JSONObject().put(Integer.toString((tokens.size() + 1)), "[line " + line + "] Error: Unterminated string."));
188 | simpleInterpreter.error(line, "Unterminated string.");
189 | return;
190 | }
191 |
192 |
193 | advance();
194 |
195 |
196 | String value = source.substring(start + 1, current - 1);
197 | addToken(STRING, value);
198 | }
199 |
200 | private boolean match(char expected) {
201 | if (isAtEnd()) return false;
202 | if (source.charAt(current) != expected) return false;
203 |
204 | current++;
205 | return true;
206 | }
207 |
208 |
209 | private char peek() {
210 | if (isAtEnd()) return '\0';
211 | return source.charAt(current);
212 | }
213 |
214 |
215 | private char peekNext() {
216 | if (current + 1 >= source.length()) return '\0';
217 | return source.charAt(current + 1);
218 | }
219 |
220 |
221 | private boolean isAlpha(char c) {
222 | return (c >= 'a' && c <= 'z') ||
223 | (c >= 'A' && c <= 'Z') ||
224 | c == '_';
225 | }
226 |
227 | private boolean isAlphaNumeric(char c) {
228 | return isAlpha(c) || isDigit(c);
229 | }
230 |
231 |
232 | private boolean isDigit(char c) {
233 | return c >= '0' && c <= '9';
234 | }
235 |
236 |
237 | private boolean isAtEnd() {
238 | return current >= source.length();
239 | }
240 |
241 |
242 | private char advance() {
243 | current++;
244 | return source.charAt(current - 1);
245 | }
246 |
247 | private void addToken(TokenType type) {
248 | addToken(type, null);
249 | }
250 |
251 | private void addToken(TokenType type, Object literal) {
252 | String text = source.substring(start, current);
253 | tokens.add(new Token(type, text, literal, line, start, current - 1));
254 | }
255 | }
--------------------------------------------------------------------------------
/InterpreterVisualizer/src/main/java/simpleinterpreter/AST.java:
--------------------------------------------------------------------------------
1 | package simpleinterpreter;
2 |
3 | import org.json.JSONArray;
4 | import org.json.JSONObject;
5 |
6 | import java.util.ArrayList;
7 | import java.util.List;
8 | import java.util.Map;
9 |
10 | public class AST {
11 |
12 | //Parser Data
13 | private final List astJSON;
14 | private final JSONArray visitedNode;
15 | private final List nodesData;
16 |
17 | // Interpreter Data
18 | private final JSONArray interpreterVisitedNode;
19 | private final JSONArray SymbolTableIndexSync;
20 | private final List symbolTableJSON;
21 | private final List interpreterNodesData;
22 | private final JSONObject outputMessages;
23 | private final JSONObject runtimeErrors;
24 |
25 |
26 | private final String ID = "\"id\"";
27 | private final String NEXT = "\"next\"";
28 |
29 | AST() {
30 | astJSON = new ArrayList<>();
31 | visitedNode = new JSONArray();
32 | nodesData = new ArrayList<>();
33 |
34 | interpreterVisitedNode = new JSONArray();
35 | symbolTableJSON = new ArrayList<>();
36 | SymbolTableIndexSync = new JSONArray();
37 | interpreterNodesData = new ArrayList<>();
38 | outputMessages = new JSONObject();
39 | runtimeErrors = new JSONObject();
40 | }
41 |
42 |
43 | /* Traversing AST during Semantic Analysis */
44 |
45 | void initInterpreterAST(Environment environment) {
46 | int rootIndex = getLastVisitedNodeIndex();
47 | interpreterVisitedNode.put(rootIndex);
48 | JSONObject lastDataJSONObject = new JSONObject(getLastJSONObject().toString());
49 | interpreterNodesData.add(lastDataJSONObject);
50 | JSONObject symbolTable = buildSymbolTable(environment, 1);
51 | symbolTableJSON.add(symbolTable);
52 | SymbolTableIndexSync.put(0);
53 | }
54 |
55 | void reportRuntimeError(String message) {
56 | int index = interpreterVisitedNode.length() - 1;
57 | runtimeErrors.put(Integer.toString(index), message);
58 | }
59 |
60 | void printOutputMessage(String message) {
61 | int index = interpreterVisitedNode.length() - 1;
62 | outputMessages.put(Integer.toString(index), message);
63 | }
64 |
65 | void addNodeDataInterpreter(int index, List data) {
66 | //Data
67 | JSONObject lastDataJSONObject = new JSONObject(getInterpreterLastJSONObject().toString());
68 | if (!data.isEmpty()) {
69 | for (String s : data) {
70 | lastDataJSONObject.append(Integer.toString(index), s);
71 | }
72 | }
73 | interpreterNodesData.add(lastDataJSONObject);
74 | }
75 |
76 | JSONObject buildSymbolTable(Environment environment, int scope) {
77 | JSONObject variables = new JSONObject();
78 |
79 | Map values = environment.getValues();
80 | for (String name : values.keySet()) {
81 | variables.put(name, values.get(name));
82 | }
83 |
84 | JSONObject scopes;
85 | if (environment.enclosing != null) {
86 | scopes = buildSymbolTable(environment.enclosing, scope + 1);
87 | } else {
88 | scopes = new JSONObject();
89 | }
90 |
91 | if (!variables.isEmpty())
92 | scopes.put(Integer.toString(scope), variables);
93 |
94 | return scopes;
95 | }
96 |
97 | void updateSymbolTable(Environment environment) {
98 | JSONObject symbolTable = buildSymbolTable(environment, 1);
99 | symbolTableJSON.add(symbolTable);
100 | }
101 |
102 | void visitNodeInterpreter(int index, String... args) {
103 | interpreterVisitedNode.put(index);
104 | SymbolTableIndexSync.put(symbolTableJSON.size() - 1);
105 |
106 | ArrayList data = new ArrayList<>();
107 |
108 | for (String s : args) {
109 | data.add(s);
110 | }
111 |
112 | addNodeDataInterpreter(index, data);
113 | }
114 |
115 | private JSONObject getInterpreterLastJSONObject() {
116 | int size = interpreterNodesData.size();
117 | if (size == 0)
118 | return new JSONObject();
119 | return interpreterNodesData.get(size - 1);
120 | }
121 |
122 | /* Building AST during Parsing */
123 |
124 | void addNodeData(int index, List data) {
125 | //Data
126 | JSONObject lastDataJSONObject = new JSONObject(getLastJSONObject().toString());
127 | if (!data.isEmpty()) {
128 | for (String s : data) {
129 | lastDataJSONObject.append(Integer.toString(index), s);
130 | }
131 | }
132 | nodesData.add(lastDataJSONObject);
133 | }
134 |
135 | void addNewNode(int index, List data, List neighbours) {
136 | //I'm supposed to draw one edge from (index) to other nodes indices in args
137 | //args also has some data the I need to add to node (Index)
138 |
139 | addNodeData(index, data);
140 |
141 | JSONArray lastJSONArray = new JSONArray(getLastJSONArray().toString());
142 |
143 | visitedNode.put(index);
144 |
145 | JSONObject currentNode = new JSONObject();
146 | currentNode.put(ID, toStringWithDoubleQuotes(index));
147 | currentNode.put(NEXT, new JSONArray());
148 | for (int to : neighbours) {
149 | currentNode.append(NEXT, toStringWithDoubleQuotes(to));
150 | }
151 |
152 | lastJSONArray.put(currentNode);
153 | astJSON.add(lastJSONArray);
154 | }
155 |
156 | /* Helper Functions */
157 |
158 | private JSONArray getLastJSONArray() {
159 | int size = astJSON.size();
160 | if (size == 0)
161 | return new JSONArray();
162 | return astJSON.get(size - 1);
163 | }
164 |
165 | private JSONObject getLastJSONObject() {
166 | int size = nodesData.size();
167 | if (size == 0)
168 | return new JSONObject();
169 | return nodesData.get(size - 1);
170 | }
171 |
172 | private int getLastVisitedNodeIndex() {
173 | int size = visitedNode.length();
174 | if (size == 0)
175 | return -1;
176 | return visitedNode.getInt(size - 1);
177 |
178 | }
179 |
180 | private String toStringWithDoubleQuotes(int index) {
181 | return "\"" + index + "\"";
182 | }
183 |
184 |
185 | /* Getters for Generating AST */
186 |
187 | int getASTsSize() {
188 | return astJSON.size();
189 | }
190 |
191 | public List getAstJSON() {
192 | return astJSON;
193 | }
194 |
195 | public JSONArray getVisitedNode() {
196 | return visitedNode;
197 | }
198 |
199 | public JSONArray getNodesData() {
200 | JSONArray nodesDataJSONArray = new JSONArray();
201 | for (JSONObject jsonObject : nodesData) {
202 | nodesDataJSONArray.put(jsonObject);
203 | }
204 | return nodesDataJSONArray;
205 | }
206 |
207 |
208 | /* Getters for Traversing AST */
209 |
210 | public JSONObject getInterpreterRuntimeErrors() {
211 | return runtimeErrors;
212 | }
213 |
214 | JSONArray getInterpreterCompleteAST() {
215 | return getLastJSONArray();
216 | }
217 |
218 | public JSONArray getInterpreterVisitedNode() {
219 | return interpreterVisitedNode;
220 | }
221 |
222 | public List getInterpreterNodesData() {
223 | return interpreterNodesData;
224 | }
225 |
226 | public JSONObject getInterpreterOutputMessages() {
227 | return outputMessages;
228 | }
229 |
230 | public JSONArray getSymbolTableIndexSync() {
231 | return SymbolTableIndexSync;
232 | }
233 |
234 | public List getSymbolTableJSON() {
235 | return symbolTableJSON;
236 | }
237 | }
238 |
--------------------------------------------------------------------------------
/lib/ui_elements/control_buttons.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutterdesktopapp/models/tokens.dart';
3 | import 'package:flutterdesktopapp/services/networking.dart';
4 | import 'package:flutterdesktopapp/utils/app_data.dart';
5 | import 'package:flutterdesktopapp/utils/constants.dart';
6 | import 'package:flutterdesktopapp/utils/utilities_provider.dart';
7 | import 'package:provider/provider.dart';
8 |
9 | class ControlButtons extends StatefulWidget {
10 | @override
11 | _ControlButtonsState createState() => _ControlButtonsState();
12 | }
13 |
14 | class _ControlButtonsState extends State {
15 | NetworkHelper networkHelper = NetworkHelper();
16 |
17 | @override
18 | Widget build(BuildContext context) {
19 | final appData = Provider.of(context);
20 | final utilsProvider =
21 | Provider.of(context, listen: false);
22 |
23 | String getText() {
24 | if (appData.isVisualized &&
25 | (appData.circleOneClicked ||
26 | appData.circleTwoClicked ||
27 | appData.circleThreeClicked ||
28 | appData.circleFourClicked))
29 | return "Back";
30 | else
31 | return "Visualize";
32 | }
33 |
34 | Function getPrevButtonFunc() {
35 | var twoORthree = appData.circleTwoClicked | appData.circleThreeClicked;
36 | if (twoORthree && appData.visualizedStatementIndex > 0) {
37 | return () {
38 | appData.visualizedStatementIndex--;
39 | };
40 | }
41 | return null;
42 | }
43 |
44 | Function getNextButtonFunc() {
45 | var twoORthree = appData.circleTwoClicked | appData.circleThreeClicked;
46 | if (twoORthree &&
47 | appData.visualizedStatementIndex + 1 <
48 | appData.parsedStatementsList.length) {
49 | return () {
50 | appData.visualizedStatementIndex++;
51 | };
52 | }
53 | return null;
54 | }
55 |
56 | void showAlertDialog(BuildContext context) {
57 | Widget okButton = ElevatedButton(
58 | child: Text("OK"),
59 | onPressed: () {
60 | Navigator.of(context).pop();
61 | },
62 | );
63 |
64 | AlertDialog alert = AlertDialog(
65 | title: Text("Notice"),
66 | content: Text(
67 | "Please, write down some code before attempting to visualize!"),
68 | actions: [
69 | okButton,
70 | ],
71 | );
72 |
73 | showDialog(
74 | context: context,
75 | builder: (BuildContext context) {
76 | return alert;
77 | },
78 | );
79 | }
80 |
81 | void compile(List consoleMessages) {
82 | utilsProvider.addConsoleMessageList(consoleMessages);
83 |
84 | var sourceCode = appData.editingController.text;
85 | var richTextList = [], tokensColors = [], tokensIndices = [];
86 | int lastEnd, shift = 0;
87 | var tokensList = appData.tokensList;
88 |
89 | for (int tokenIndex = 0; tokenIndex < tokensList.length; tokenIndex++) {
90 | Token token = tokensList[tokenIndex];
91 |
92 | var start = token.start - shift;
93 | var end = token.end - shift;
94 | if (tokenIndex > 0) {
95 | // no between text before the first token
96 | var betweenText = sourceCode.substring(lastEnd + 1, start);
97 |
98 | if (betweenText.length > 1 && betweenText[0] == "\n") {
99 | // betweenText = "\n";
100 | // shift += 2 * betweenText.length;
101 | // start -= betweenText.length;
102 | // end -= betweenText.length;
103 | }
104 | richTextList.add([betweenText, Colors.black, 0]);
105 |
106 | tokensColors.add(Colors.black);
107 | }
108 | if (token.tokenType != "EOF") {
109 | // no between text after EOF
110 | var tokenText = sourceCode.substring(start, end + 1);
111 | print(tokenText);
112 | richTextList.add([tokenText, Colors.black, 1]);
113 | }
114 | lastEnd = end;
115 | tokensIndices.add(tokensColors.length);
116 | tokensColors.add(tokensList[tokenIndex].color);
117 | }
118 |
119 | appData.tokensIndices = tokensIndices;
120 | utilsProvider.richTextList = richTextList;
121 | appData.tokensColors = tokensColors;
122 |
123 | appData.visualize();
124 | }
125 |
126 | void callInterpreter(String string, var context) {
127 | // final progress = ProgressHUD.of(context);
128 | // progress.show();
129 | List consoleMessages = [];
130 | networkHelper
131 | .sendCodeToInterpreter(appData.editingController.text.toString())
132 | .then((resultMessages) {
133 | consoleMessages = resultMessages;
134 |
135 | networkHelper.getLexicalAnalysis().then((value) {
136 | appData.tokensList = value;
137 | if (value != null) {
138 | consoleMessages.add(
139 | ["Requesting Lexical Analysis Completed Successfully!", 1]);
140 | } else
141 | consoleMessages.add(["Failed to receive lexical analysis.", 0]);
142 |
143 | networkHelper.getSyntacticAnalysis().then((value) {
144 | appData.parsedStatementsList = value;
145 | if (value != null) {
146 | consoleMessages.add(
147 | ["Requesting Syntactic Analysis Completed Successfully!", 1]);
148 | } else
149 | consoleMessages.add(["Failed to receive syntactic analysis.", 0]);
150 |
151 | networkHelper.getSemanticAnalysis().then((value) {
152 | appData.astsList = value;
153 | if (value != null) {
154 | consoleMessages.add([
155 | "Requesting Semantic Analysis Completed Successfully!",
156 | 1
157 | ]);
158 | } else
159 | consoleMessages
160 | .add(["Failed to receive semantic analysis.", 0]);
161 |
162 | compile(consoleMessages);
163 | });
164 | });
165 | });
166 | });
167 | }
168 |
169 | void _VisualizeButtonLogic(BuildContext context) {
170 | appData.isVisualizationReady = false;
171 | utilsProvider.clearConsoleMessages();
172 | if (appData.editingController.text.isEmpty) {
173 | showAlertDialog(context);
174 | } else {
175 | callInterpreter(appData.editingController.text, context);
176 | }
177 | }
178 |
179 | void _BackButtonLogic() {
180 | if (appData.circleOneClicked) {
181 | appData.changeCircleOneState();
182 | } else if (appData.circleTwoClicked) {
183 | appData.changeCircleTwoState();
184 | } else if (appData.circleThreeClicked) {
185 | appData.changeCircleThreeState();
186 | }
187 | utilsProvider.resetRichTextListColors();
188 | appData.visualizedStatementIndex = 0;
189 | }
190 |
191 | Function getVisualizeButtonFunc(var context) {
192 | var atLeastOneCircle = appData.atLeastOneCircle();
193 |
194 | if (atLeastOneCircle) {
195 | return () {
196 | _BackButtonLogic();
197 | };
198 | }
199 | if (appData.isVisualizationReady || atLeastOneCircle)
200 | return () {
201 | _VisualizeButtonLogic(context);
202 | };
203 | return null;
204 | }
205 |
206 | return Padding(
207 | padding: const EdgeInsets.all(5.0),
208 | child: Row(
209 | mainAxisAlignment: MainAxisAlignment.spaceEvenly,
210 | children: [
211 | Expanded(
212 | child: Padding(
213 | padding: const EdgeInsets.only(left: 4.0, right: 4.0),
214 | child: ElevatedButton(
215 | onPressed: getVisualizeButtonFunc(context),
216 | child: Text(
217 | getText(),
218 | style: text_style_header_button,
219 | ),
220 | style: run_button_style,
221 | ),
222 | ),
223 | ),
224 | Expanded(
225 | child: Padding(
226 | padding: const EdgeInsets.only(left: 4.0, right: 4.0),
227 | child: ElevatedButton(
228 | onPressed: getPrevButtonFunc(),
229 | style: run_button_style,
230 | child: Text(
231 | "Previous Statement",
232 | style: text_style_header_button,
233 | )),
234 | ),
235 | ),
236 | Expanded(
237 | child: Padding(
238 | padding: const EdgeInsets.only(left: 4.0, right: 4.0),
239 | child: ElevatedButton(
240 | onPressed: getNextButtonFunc(),
241 | style: run_button_style,
242 | child:
243 | Text("Next Statement", style: text_style_header_button)),
244 | ),
245 | )
246 | ],
247 | ),
248 | );
249 | }
250 | }
251 |
--------------------------------------------------------------------------------