commit 7114c0e97892c8c60a0bfe5d0c0406b723367ad4 Author: Dimitri Lajou Date: Fri Mar 21 17:26:31 2025 +0100 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9aa60ef --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +.gradle +build +bin +*.ll +*.DS_Store diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..b97bdc5 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,9 @@ +{ + "java.server.launchMode": "Standard", + "java.gradle.buildServer.enabled": "on", + "antlr4.generation": { + "mode": "none" // Don't generate source file with the antlr4-vscode extension + }, + "java.configuration.updateBuildConfiguration": "automatic", + "java.inlayHints.parameterNames.enabled": "none" +} diff --git a/README.md b/README.md new file mode 100644 index 0000000..e0f35ce --- /dev/null +++ b/README.md @@ -0,0 +1,45 @@ +# TP2 PDS - VSL+ + +Ce projet VSCode contient tout le nécessaire pour commencer à programmer le compilateur. + +Vous pouvez forker ce dépôt, mais devez impérativement garder votre dépôt privé. + +Ce fichier `README.md` doit être complété au fur et à mesure de votre avancement. + +## Compatibilité + +- Java JDK 21 +- ANTLR3 3.5.2 +- Gradle 8.5 + +## Construction, exécution + +Pour construire le projet, depuis la racine du projet : + +```bash +./gradlew build +``` + +Pour exécuter le programme Java TP2.Main, depuis la racine du projet : +```bash +java -jar /build/libs/TP2.jar [args] +``` + +## Structure du projet + +Fichiers de code source et de tests +- `src/main/java/` : fichiers sources Java à compléter +- `src/main/antlr/` : fichier sources ANTLR à compléter +- `tests/` : fichiers textes à utiliser pour les tests + +Moteur de production Gradle +- `settings.gradle`, `build.gradle` : configuration Gradle +- `gradle/wrapper` : exécutable de Wrapper Gradle +- `gradlew`, `gradlew.bat` : scripts (unix/windows) à exécuter depuis le terminal pour lancer le moteur de production + +Environnement VSCode +- `.vscode` : configuration de VSCode +- `eclipse-formatter.xml` : formatage de code source Java, optionnel + +Git +- `.gitignore` : configuration pour ignorer certains fichiers et répertoires diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..31ef3ab --- /dev/null +++ b/build.gradle @@ -0,0 +1,34 @@ +plugins { + id 'java' + id 'antlr' +} + +repositories { + mavenCentral() +} + +dependencies { + // use ANTLR version 3, with explicit k for LL(k) + antlr "org.antlr:antlr:3.5.2" + implementation 'org.pcollections:pcollections:4.0.2' +} + +java { + sourceCompatibility = "1.21" + targetCompatibility = "1.21" +} + +generateGrammarSource { + arguments += [ '-no-visitor', '-no-listener' ] + outputDirectory = new File(buildDir.toString() + "/generated-src/antlr/main/TP2/") +} + +jar { + manifest { + attributes ( + 'Main-Class': 'TP2.Main', + 'Class-Path': configurations.runtimeClasspath.files.collect { "file:///" + it.canonicalPath }.join(' ') + + ) + } +} \ No newline at end of file diff --git a/compile b/compile new file mode 100755 index 0000000..c90b242 --- /dev/null +++ b/compile @@ -0,0 +1,16 @@ +#!/bin/sh + +# stop script at first fail +set -e + +if [ "$#" -ne 1 ] ; then + echo "usage: $0 file.vsl" + exit 0 +fi + +name="`dirname $1`/`basename $1 .vsl`" + +# translating from VSL to LLVM IR (.ll) +java -jar build/libs/TP2.jar < $name.vsl > $name.ll + +clang $name.ll -o $name diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..e708b1c Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..7cf0814 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,7 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip +networkTimeout=10000 +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists \ No newline at end of file diff --git a/gradlew b/gradlew new file mode 100755 index 0000000..1aa94a4 --- /dev/null +++ b/gradlew @@ -0,0 +1,249 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..6689b85 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,92 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/runAllTests.py b/runAllTests.py new file mode 100755 index 0000000..e3595c5 --- /dev/null +++ b/runAllTests.py @@ -0,0 +1,141 @@ +#!/usr/bin/env python3 + +import os +import subprocess + +from colorama import init as colorama_init +from colorama import Fore +from colorama import Style + +stats = {} + +def runTestNormalLevel(level): + print(f"Running test of level {level}") + stats[level] = (0,0,0,0) + for dirname, dirnames, filenames in os.walk(f'./tests/testlevel{level}'): + for filename in filenames: + runNormalTest(level, dirname, filename) + +def runNormalTest(i, dirname,filename): + vslToLLVM = False + llvmToBin = False + executionCorrect = False + + path = os.path.join(dirname, filename) + basename, ext = os.path.splitext(path) + # Ignore not .vsl files + if ext != ".vsl": + return + + print(f'\tRunning test {filename}') + + # VSL -> LLVM + p = subprocess.run(f"java -jar build/libs/TP2.jar < {path} 1>{basename}.ll", shell=True) + if p.returncode == 0 : + vslToLLVM = True + + + # LLVM -> Bin + if vslToLLVM : + p = subprocess.run(f"clang {basename}.ll -o {basename} 2>/dev/null", shell=True) + if p.returncode == 0: + llvmToBin = True + executionCorrect = True + + # Exe + if llvmToBin : + try: + if os.path.isfile(f"{basename}.test_in"): + p = subprocess.run(f"./{basename} < {basename}.test_in", shell=True, stdout=subprocess.PIPE, timeout=10) + else: + p = subprocess.run(f"./{basename}", shell=True, stdout=subprocess.PIPE, timeout=10) + except subprocess.TimeoutExpired: + executionCorrect = basename == "./tests/testlevel4/level4diverge" + + # Check return code + if os.path.isfile(f"{basename}.test_ret"): + with open(f"{basename}.test_ret", "r") as expected: + executionCorrect = int(expected.read()) == p.returncode + # Check stdout + if os.path.isfile(f"{basename}.test_out"): + with open(f"{basename}.test_out", "rb") as expected: + executionCorrect = executionCorrect and expected.read() == p.stdout + + + print(f"{colorFromBool(vslToLLVM)}\t\tVSL to LLVM : {'OK' if vslToLLVM else 'Fail'}{Style.RESET_ALL}") + print(f"{colorFromBool(llvmToBin)}\t\tLLVM to Bin : {'OK' if llvmToBin else 'Fail'}{Style.RESET_ALL}") + print(f"{colorFromBool(executionCorrect)}\t\tCorrect Execution : {'OK' if executionCorrect else 'Fail'}{Style.RESET_ALL}") + + x,y,z,t = stats[i] + if vslToLLVM : + x += 1 + if llvmToBin : + y += 1 + if executionCorrect : + z += 1 + t += 1 + stats[i] = (x,y,z,t) + +def colorFromBool(b): + if b: + return Fore.GREEN + else: + return Fore.RED + + +def afficheStats(stat): + x,y,z,t = stat + print(f'\t Nombre de tests : {t}') + print(f'{colorFromBool(x==t)}\t vsl to llvm : {x} / {t}{Style.RESET_ALL}') + print(f'{colorFromBool(y==t)}\t llvm to bin : {y} / {t}{Style.RESET_ALL}') + print(f'{colorFromBool(z==t)}\t resultat correct: {z} / {t}{Style.RESET_ALL}') + +nbError = 0 +nbErrorTests = 0 + +def runErrorTest(dirname,filename): + path = os.path.join(dirname, filename) + basename, ext = os.path.splitext(path) + if ext != ".vsl": + return + + print(f'\tRunning test {filename}') + + global nbErrorTests + nbErrorTests = nbErrorTests + 1 + + p = subprocess.run(f"java -jar build/libs/TP2.jar < {path} 1>{basename}.ll", shell=True, stderr=subprocess.PIPE) + if p.returncode != 0 and p.stderr != b'': + print(f"\t\t{Fore.GREEN}Error : Yes{Style.RESET_ALL}") + global nbError + nbError = nbError + 1 + return 1 + else: + print(f"\t\t{Fore.RED}Error : No{Style.RESET_ALL}") + return 0 + +def runErrorLevelTests(): + print(f"Running test of level error") + for dirname, dirnames, filenames in os.walk(f'./tests/testlevelerror'): + # print path to all filenames. + for filename in filenames: + runErrorTest( dirname, filename) + + +def runTests(testDirname): + for i in range(1,5): + runTestNormalLevel(i) + runErrorLevelTests() + + for i in range(1,5): + print(f'Résumé du level {i}') + afficheStats(stats[i]) + print(f'Résumé du level error') + print(f'{colorFromBool(nbError==nbErrorTests)}\t Nombre d\'erreurs : {nbError} / {nbErrorTests}{Style.RESET_ALL}') + + + + +if __name__ == "__main__" : + colorama_init() + runTests("tests") \ No newline at end of file diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..f688920 --- /dev/null +++ b/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'TP2' diff --git a/src/main/antlr/VSLLexer.g b/src/main/antlr/VSLLexer.g new file mode 100644 index 0000000..5eb1b72 --- /dev/null +++ b/src/main/antlr/VSLLexer.g @@ -0,0 +1,22 @@ +lexer grammar VSLLexer; + +options { + language = Java; +} + +@header { + package TP2; +} + +WS : (' '|'\n'|'\t') { skip(); } + ; + +COMMENT : '//' (~'\n')* { skip(); } + ; + +fragment LETTER : 'a'..'z' ; +fragment DIGIT : '0'..'9' ; +fragment ASCII : ~('\n'|'"'); + + + diff --git a/src/main/antlr/VSLParser.g b/src/main/antlr/VSLParser.g new file mode 100644 index 0000000..e3fd426 --- /dev/null +++ b/src/main/antlr/VSLParser.g @@ -0,0 +1,24 @@ +parser grammar VSLParser; + +options { + language = Java; + tokenVocab = VSLLexer; + k = 1; +} + +@header { + package TP2; + + import TP2.asd.*; +} + +// On syntax error, raise exception rather than silently recovery +@rulecatch { + catch (RecognitionException ex) { + reportError(ex) ; + throw(ex) ; + } +} + + +program returns [Program p] : /* TODO */; diff --git a/src/main/java/TP2/Main.java b/src/main/java/TP2/Main.java new file mode 100644 index 0000000..5c5618d --- /dev/null +++ b/src/main/java/TP2/Main.java @@ -0,0 +1,51 @@ +package TP2; + +import java.nio.file.Paths; +import java.util.Optional; +import java.io.IOException; + +import org.antlr.runtime.ANTLRFileStream; +import org.antlr.runtime.ANTLRInputStream; +import org.antlr.runtime.CharStream; +import org.antlr.runtime.CommonTokenStream; +import org.antlr.runtime.RecognitionException; + +import TP2.asd.Program; + +public class Main { + public static void main(String[] args) { + try { + // Set input + CharStream input; + if (args.length == 0) { + // From standard input + input = new ANTLRInputStream(System.in); + } else { + // From file name in first argument + input = new ANTLRFileStream(args[0]); + } + + // Instantiate Lexer + VSLLexer lexer = new VSLLexer(input); + CommonTokenStream tokens = new CommonTokenStream(lexer); + + // Instantiate Parser + VSLParser parser = new VSLParser(tokens); + + // Parse + Program ast = parser.program(); + + // Pretty-print the program (to debug parsing) + System.err.println("todo"); + + // Verify the program semantic + + // Generate the intermediate representation + System.out.println("todo"); + + } catch (IOException | RecognitionException e) { + e.printStackTrace(); + throw new RuntimeException("Unable to proceed"); + } + } +} diff --git a/src/main/java/TP2/asd/Program.java b/src/main/java/TP2/asd/Program.java new file mode 100644 index 0000000..7d4a814 --- /dev/null +++ b/src/main/java/TP2/asd/Program.java @@ -0,0 +1,5 @@ +package TP2.asd; + +public record Program() { + +} diff --git a/src/main/java/TP2/llvm/LLVMString.java b/src/main/java/TP2/llvm/LLVMString.java new file mode 100644 index 0000000..bab31b5 --- /dev/null +++ b/src/main/java/TP2/llvm/LLVMString.java @@ -0,0 +1,5 @@ +package TP2.llvm; + +public record LLVMString(String data, int size) { + +} diff --git a/src/main/java/TP2/llvm/Utils.java b/src/main/java/TP2/llvm/Utils.java new file mode 100644 index 0000000..49d883b --- /dev/null +++ b/src/main/java/TP2/llvm/Utils.java @@ -0,0 +1,81 @@ +package TP2.llvm; + +import java.util.regex.Pattern; +import java.util.regex.Matcher; + +public class Utils { + private static int tmp = 0; + private static int lab = 0; + private static int glob = 0; + private final static Pattern re = Pattern.compile("\\\\n"); + + /** + * Generate a new unique local identifier (starting with %tmp) + * + * @return the identifier + */ + public static String newtmp() { + return newVar("tmp"); + } + + /** + * Generate a new unique local identifier (starting with %) for a variable + * + * @return the identifier + */ + public static String newVar(String prefix) { + tmp++; + return "%" + prefix + tmp; + } + + /** + *

+ * generate a new unique label starting with str + *

+ * + * ex: newlab("if") may return "if24" + * + * @param str the start of the label + * @return the label name + */ + public static String newlab(String str) { + lab++; + return str + lab; + } + + /** + * generate a new unique global identifier (starting with @) + * + * @param str the start of the name of the identifier + * @return the name of the identifier + */ + public static String newglob(String str) { + glob++; + return "@" + str + glob; + } + + /** + * Transform escaped newlines ('\' 'n') into newline form suitable for LLVM and + * append the NUL character (end of string) + * + * @param str the input string + * @return a pair: the new String, and its size (according to LLVM) + */ + public static LLVMString stringTransform(String str) { + Matcher m = re.matcher(str); + StringBuffer res = new StringBuffer(); + int count = 0; + + while (m.find()) { + m.appendReplacement(res, "\\\\0A"); + count++; + } + + m.appendTail(res).append("\\00"); + + // + 1 for \00 + // - 1 by \n because each ('\' '\n') is transformed into one char + return new LLVMString(res.toString(), 1 + str.length() - count); + } + +} diff --git a/tests/aLaMain.vsl b/tests/aLaMain.vsl new file mode 100644 index 0000000..26ec141 --- /dev/null +++ b/tests/aLaMain.vsl @@ -0,0 +1 @@ + FUNC INT main() RETURN 0 + 1 + 2 \ No newline at end of file diff --git a/tests/testlevel1/hello_world.test_out b/tests/testlevel1/hello_world.test_out new file mode 100644 index 0000000..5e1c309 --- /dev/null +++ b/tests/testlevel1/hello_world.test_out @@ -0,0 +1 @@ +Hello World \ No newline at end of file diff --git a/tests/testlevel1/hello_world.vsl b/tests/testlevel1/hello_world.vsl new file mode 100644 index 0000000..3035c56 --- /dev/null +++ b/tests/testlevel1/hello_world.vsl @@ -0,0 +1,4 @@ +FUNC VOID main() { + PRINT "Hello World" + } + diff --git a/tests/testlevel1/level1block.test_ret b/tests/testlevel1/level1block.test_ret new file mode 100644 index 0000000..c227083 --- /dev/null +++ b/tests/testlevel1/level1block.test_ret @@ -0,0 +1 @@ +0 \ No newline at end of file diff --git a/tests/testlevel1/level1block.vsl b/tests/testlevel1/level1block.vsl new file mode 100644 index 0000000..a9cace8 --- /dev/null +++ b/tests/testlevel1/level1block.vsl @@ -0,0 +1,2 @@ +FUNC INT main() { RETURN 0 } + diff --git a/tests/testlevel1/level1expr.test_out b/tests/testlevel1/level1expr.test_out new file mode 100644 index 0000000..ec77679 --- /dev/null +++ b/tests/testlevel1/level1expr.test_out @@ -0,0 +1,7 @@ +5+7 = 12 +5-7 = -2 +5*7 = 35 +5/7 = 0 +5+1 = 6 +5* (5+7) = 60 +5* 5+7 = 32 diff --git a/tests/testlevel1/level1expr.vsl b/tests/testlevel1/level1expr.vsl new file mode 100644 index 0000000..b95181a --- /dev/null +++ b/tests/testlevel1/level1expr.vsl @@ -0,0 +1,10 @@ +FUNC VOID main() { + PRINT 5,"+",7," = ", 5+7 ,"\n" + PRINT 5,"-",7," = ", 5-7 ,"\n" + PRINT 5,"*",7," = ", 5*7 ,"\n" + PRINT 5,"/",7," = ", 5/7 ,"\n" + PRINT 5,"+",1," = ", 5+1 ,"\n" + PRINT 5,"* (",5,"+",7,") = ", 5*(5+7) ,"\n" + PRINT 5,"* ",5,"+",7," = ", 5 * 5 + 7 ,"\n" + } + diff --git a/tests/testlevel1/level1function.test_ret b/tests/testlevel1/level1function.test_ret new file mode 100644 index 0000000..c227083 --- /dev/null +++ b/tests/testlevel1/level1function.test_ret @@ -0,0 +1 @@ +0 \ No newline at end of file diff --git a/tests/testlevel1/level1function.vsl b/tests/testlevel1/level1function.vsl new file mode 100644 index 0000000..650f7eb --- /dev/null +++ b/tests/testlevel1/level1function.vsl @@ -0,0 +1 @@ +FUNC INT main() RETURN 0 diff --git a/tests/testlevel1/level1if1.test_ret b/tests/testlevel1/level1if1.test_ret new file mode 100644 index 0000000..56a6051 --- /dev/null +++ b/tests/testlevel1/level1if1.test_ret @@ -0,0 +1 @@ +1 \ No newline at end of file diff --git a/tests/testlevel1/level1if1.vsl b/tests/testlevel1/level1if1.vsl new file mode 100644 index 0000000..409b3d2 --- /dev/null +++ b/tests/testlevel1/level1if1.vsl @@ -0,0 +1,2 @@ +FUNC INT main() IF 1 THEN RETURN 1 FI + diff --git a/tests/testlevel1/level1if2.test_ret b/tests/testlevel1/level1if2.test_ret new file mode 100644 index 0000000..56a6051 --- /dev/null +++ b/tests/testlevel1/level1if2.test_ret @@ -0,0 +1 @@ +1 \ No newline at end of file diff --git a/tests/testlevel1/level1if2.vsl b/tests/testlevel1/level1if2.vsl new file mode 100644 index 0000000..2a79461 --- /dev/null +++ b/tests/testlevel1/level1if2.vsl @@ -0,0 +1,2 @@ +FUNC INT main() IF 1 THEN RETURN 1 ELSE RETURN 0 FI + diff --git a/tests/testlevel1/level1print1.test_out b/tests/testlevel1/level1print1.test_out new file mode 100644 index 0000000..5ab2f8a --- /dev/null +++ b/tests/testlevel1/level1print1.test_out @@ -0,0 +1 @@ +Hello \ No newline at end of file diff --git a/tests/testlevel1/level1print1.vsl b/tests/testlevel1/level1print1.vsl new file mode 100644 index 0000000..0c96b2b --- /dev/null +++ b/tests/testlevel1/level1print1.vsl @@ -0,0 +1 @@ +FUNC VOID main() PRINT "Hello" diff --git a/tests/testlevel1/level1print2.test_out b/tests/testlevel1/level1print2.test_out new file mode 100644 index 0000000..56a6051 --- /dev/null +++ b/tests/testlevel1/level1print2.test_out @@ -0,0 +1 @@ +1 \ No newline at end of file diff --git a/tests/testlevel1/level1print2.vsl b/tests/testlevel1/level1print2.vsl new file mode 100644 index 0000000..6223214 --- /dev/null +++ b/tests/testlevel1/level1print2.vsl @@ -0,0 +1,2 @@ +FUNC VOID main() PRINT 1 + diff --git a/tests/testlevel1/level1print3.test_out b/tests/testlevel1/level1print3.test_out new file mode 100644 index 0000000..a8b98ea --- /dev/null +++ b/tests/testlevel1/level1print3.test_out @@ -0,0 +1 @@ +1 = 1 \ No newline at end of file diff --git a/tests/testlevel1/level1print3.vsl b/tests/testlevel1/level1print3.vsl new file mode 100644 index 0000000..198e3ec --- /dev/null +++ b/tests/testlevel1/level1print3.vsl @@ -0,0 +1,2 @@ +FUNC VOID main() PRINT "1 = ", 1 + diff --git a/tests/testlevel1/level1proto.test_ret b/tests/testlevel1/level1proto.test_ret new file mode 100644 index 0000000..c227083 --- /dev/null +++ b/tests/testlevel1/level1proto.test_ret @@ -0,0 +1 @@ +0 \ No newline at end of file diff --git a/tests/testlevel1/level1proto1.vsl b/tests/testlevel1/level1proto1.vsl new file mode 100644 index 0000000..5b6b312 --- /dev/null +++ b/tests/testlevel1/level1proto1.vsl @@ -0,0 +1,2 @@ +PROTO INT main() +FUNC INT main() RETURN 0 diff --git a/tests/testlevel1/level1sequence.test_out b/tests/testlevel1/level1sequence.test_out new file mode 100644 index 0000000..2559659 --- /dev/null +++ b/tests/testlevel1/level1sequence.test_out @@ -0,0 +1 @@ +tototiti \ No newline at end of file diff --git a/tests/testlevel1/level1sequence.vsl b/tests/testlevel1/level1sequence.vsl new file mode 100644 index 0000000..a1a3f78 --- /dev/null +++ b/tests/testlevel1/level1sequence.vsl @@ -0,0 +1,3 @@ +FUNC VOID main() { PRINT "toto" PRINT "titi" } + + diff --git a/tests/testlevel1/level1while1.test_ret b/tests/testlevel1/level1while1.test_ret new file mode 100644 index 0000000..c227083 --- /dev/null +++ b/tests/testlevel1/level1while1.test_ret @@ -0,0 +1 @@ +0 \ No newline at end of file diff --git a/tests/testlevel1/level1while1.vsl b/tests/testlevel1/level1while1.vsl new file mode 100644 index 0000000..c526011 --- /dev/null +++ b/tests/testlevel1/level1while1.vsl @@ -0,0 +1,2 @@ +FUNC INT main() WHILE 1 DO RETURN 0 DONE + diff --git a/tests/testlevel2/level2assign.test_in b/tests/testlevel2/level2assign.test_in new file mode 100644 index 0000000..4d446d8 --- /dev/null +++ b/tests/testlevel2/level2assign.test_in @@ -0,0 +1,2 @@ +7 + diff --git a/tests/testlevel2/level2assign.test_out b/tests/testlevel2/level2assign.test_out new file mode 100644 index 0000000..e677a63 --- /dev/null +++ b/tests/testlevel2/level2assign.test_out @@ -0,0 +1 @@ +y vaut 7 \ No newline at end of file diff --git a/tests/testlevel2/level2assign.vsl b/tests/testlevel2/level2assign.vsl new file mode 100644 index 0000000..24c4278 --- /dev/null +++ b/tests/testlevel2/level2assign.vsl @@ -0,0 +1,6 @@ +FUNC VOID main() { + INT x,y + READ x + y := x + PRINT "y vaut ",y + } \ No newline at end of file diff --git a/tests/testlevel2/level2call.test_out b/tests/testlevel2/level2call.test_out new file mode 100644 index 0000000..0a7374a --- /dev/null +++ b/tests/testlevel2/level2call.test_out @@ -0,0 +1 @@ +one() = 1 \ No newline at end of file diff --git a/tests/testlevel2/level2call.vsl b/tests/testlevel2/level2call.vsl new file mode 100644 index 0000000..c64a6e9 --- /dev/null +++ b/tests/testlevel2/level2call.vsl @@ -0,0 +1,4 @@ +PROTO INT one() +FUNC VOID main() { PRINT "one() = ", one() } +FUNC INT one() RETURN 1 + diff --git a/tests/testlevel2/level2call2.test_out b/tests/testlevel2/level2call2.test_out new file mode 100644 index 0000000..9d4ac92 --- /dev/null +++ b/tests/testlevel2/level2call2.test_out @@ -0,0 +1 @@ +1+3 = 4 \ No newline at end of file diff --git a/tests/testlevel2/level2call2.vsl b/tests/testlevel2/level2call2.vsl new file mode 100644 index 0000000..418d00b --- /dev/null +++ b/tests/testlevel2/level2call2.vsl @@ -0,0 +1,4 @@ +PROTO INT plus(x,y) +FUNC VOID main() PRINT "1+3 = " ,plus(1,3) + +FUNC INT plus(x,y) RETURN x+y diff --git a/tests/testlevel2/level2expr.test_out b/tests/testlevel2/level2expr.test_out new file mode 100644 index 0000000..d7877df --- /dev/null +++ b/tests/testlevel2/level2expr.test_out @@ -0,0 +1,14 @@ +1+3 = 4 +1-3 = -2 +1*3 = 3 +1/3 = 0 +1+1 = 2 +1* (1+3) = 4 +1* 1+3 = 4 +5+2 = 7 +5-2 = 3 +5*2 = 10 +5/2 = 2 +5+1 = 6 +5* (5+2) = 35 +5* 5+2 = 27 diff --git a/tests/testlevel2/level2expr.vsl b/tests/testlevel2/level2expr.vsl new file mode 100644 index 0000000..e91f570 --- /dev/null +++ b/tests/testlevel2/level2expr.vsl @@ -0,0 +1,12 @@ +PROTO VOID expr(x,y) +FUNC VOID main() { expr(1,3) expr(5,2) } +FUNC VOID expr(x,y) { + PRINT x,"+",y," = ", x+y ,"\n" + PRINT x,"-",y," = ", x-y ,"\n" + PRINT x,"*",y," = ", x*y ,"\n" + PRINT x,"/",y," = ", x/y ,"\n" + PRINT x,"+",1," = ", x+1 ,"\n" + PRINT x,"* (",x,"+",y,") = ", x*(x+y) ,"\n" + PRINT x,"* ",x,"+",y," = ", x * x + y ,"\n" + } + diff --git a/tests/testlevel2/level2if1.test_out b/tests/testlevel2/level2if1.test_out new file mode 100644 index 0000000..081c526 --- /dev/null +++ b/tests/testlevel2/level2if1.test_out @@ -0,0 +1,3 @@ +2 est different de 1 +1 est different de 2 +1 est egal a 1 diff --git a/tests/testlevel2/level2if1.vsl b/tests/testlevel2/level2if1.vsl new file mode 100644 index 0000000..e641ac1 --- /dev/null +++ b/tests/testlevel2/level2if1.vsl @@ -0,0 +1,7 @@ +PROTO VOID compare(x,y) +FUNC VOID main() { compare(2,1) compare(1,2) compare(1,1) } +FUNC VOID compare(x,y) IF x-y THEN PRINT x, " est different de ",y,"\n" + ELSE PRINT x, " est egal a ",y,"\n" + FI + + diff --git a/tests/testlevel2/level2proto.test_out b/tests/testlevel2/level2proto.test_out new file mode 100644 index 0000000..9d4ac92 --- /dev/null +++ b/tests/testlevel2/level2proto.test_out @@ -0,0 +1 @@ +1+3 = 4 \ No newline at end of file diff --git a/tests/testlevel2/level2proto.vsl b/tests/testlevel2/level2proto.vsl new file mode 100644 index 0000000..f6dbf60 --- /dev/null +++ b/tests/testlevel2/level2proto.vsl @@ -0,0 +1,5 @@ +PROTO INT plus(x,y) + +FUNC VOID main() PRINT "1+3 = ", plus(1,3) + +FUNC INT plus(x,y) RETURN x+y diff --git a/tests/testlevel2/level2read.test_in b/tests/testlevel2/level2read.test_in new file mode 100644 index 0000000..8148ef7 --- /dev/null +++ b/tests/testlevel2/level2read.test_in @@ -0,0 +1,2 @@ +3 + diff --git a/tests/testlevel2/level2read.test_out b/tests/testlevel2/level2read.test_out new file mode 100644 index 0000000..44e0639 --- /dev/null +++ b/tests/testlevel2/level2read.test_out @@ -0,0 +1 @@ +Le nombre lu est 3 \ No newline at end of file diff --git a/tests/testlevel2/level2read.vsl b/tests/testlevel2/level2read.vsl new file mode 100644 index 0000000..5836bcc --- /dev/null +++ b/tests/testlevel2/level2read.vsl @@ -0,0 +1,5 @@ +FUNC VOID main() { + INT x + READ x + PRINT "Le nombre lu est ", x +} \ No newline at end of file diff --git a/tests/testlevel3/level3block.test_in b/tests/testlevel3/level3block.test_in new file mode 100644 index 0000000..8619865 --- /dev/null +++ b/tests/testlevel3/level3block.test_in @@ -0,0 +1,3 @@ +2 +5 + diff --git a/tests/testlevel3/level3block.test_out b/tests/testlevel3/level3block.test_out new file mode 100644 index 0000000..8f31501 --- /dev/null +++ b/tests/testlevel3/level3block.test_out @@ -0,0 +1 @@ +y a l'interieur vaut 5, mais a l'exterieur du bloc il vaut 2 \ No newline at end of file diff --git a/tests/testlevel3/level3block.vsl b/tests/testlevel3/level3block.vsl new file mode 100644 index 0000000..48c11a8 --- /dev/null +++ b/tests/testlevel3/level3block.vsl @@ -0,0 +1,9 @@ +FUNC VOID main() { + INT y + READ y + { INT y + READ y + PRINT "y a l'interieur vaut ",y + } + PRINT ", mais a l'exterieur du bloc il vaut ",y +} \ No newline at end of file diff --git a/tests/testlevel3/level3block1.test_out b/tests/testlevel3/level3block1.test_out new file mode 100644 index 0000000..105d7d9 --- /dev/null +++ b/tests/testlevel3/level3block1.test_out @@ -0,0 +1 @@ +100 \ No newline at end of file diff --git a/tests/testlevel3/level3block1.vsl b/tests/testlevel3/level3block1.vsl new file mode 100644 index 0000000..651f145 --- /dev/null +++ b/tests/testlevel3/level3block1.vsl @@ -0,0 +1,5 @@ +FUNC VOID main(f) { + INT f + f:=100 + PRINT f +} diff --git a/tests/testlevel3/level3block2.test_out b/tests/testlevel3/level3block2.test_out new file mode 100644 index 0000000..e69de29 diff --git a/tests/testlevel3/level3tab1.test_in b/tests/testlevel3/level3tab1.test_in new file mode 100644 index 0000000..5a7c9e2 --- /dev/null +++ b/tests/testlevel3/level3tab1.test_in @@ -0,0 +1,4 @@ +7 +3 +1 + diff --git a/tests/testlevel3/level3tab1.test_out b/tests/testlevel3/level3tab1.test_out new file mode 100644 index 0000000..18af9ba --- /dev/null +++ b/tests/testlevel3/level3tab1.test_out @@ -0,0 +1 @@ +731 \ No newline at end of file diff --git a/tests/testlevel3/level3tab1.vsl b/tests/testlevel3/level3tab1.vsl new file mode 100644 index 0000000..572393e --- /dev/null +++ b/tests/testlevel3/level3tab1.vsl @@ -0,0 +1,5 @@ +FUNC VOID main() { + INT x, t[3] + READ t[0],t[1],t[2] + PRINT t[0], t[1], t[2] + } diff --git a/tests/testlevel3/level3tab2.test_in b/tests/testlevel3/level3tab2.test_in new file mode 100644 index 0000000..2a8d362 --- /dev/null +++ b/tests/testlevel3/level3tab2.test_in @@ -0,0 +1,4 @@ +8 +4 +2 + diff --git a/tests/testlevel3/level3tab2.test_out b/tests/testlevel3/level3tab2.test_out new file mode 100644 index 0000000..cf0a729 --- /dev/null +++ b/tests/testlevel3/level3tab2.test_out @@ -0,0 +1,3 @@ +t[0] = 8 +t[1] = 4 +t[2] = 2 \ No newline at end of file diff --git a/tests/testlevel3/level3tab2.vsl b/tests/testlevel3/level3tab2.vsl new file mode 100644 index 0000000..710c56c --- /dev/null +++ b/tests/testlevel3/level3tab2.vsl @@ -0,0 +1,8 @@ +FUNC VOID main() { + INT x,y,z, t[3] + READ x,y,z + t[0] := x + t[1] := y + t[2] := z + PRINT "t[0] = ", t[0],"\nt[1] = ", t[1],"\nt[2] = ",t[2] +} diff --git a/tests/testlevel3/level3tab3.test_in b/tests/testlevel3/level3tab3.test_in new file mode 100644 index 0000000..8c54c7d --- /dev/null +++ b/tests/testlevel3/level3tab3.test_in @@ -0,0 +1,9 @@ +8 +4 +6 +2 +5 +1 +3 +7 + diff --git a/tests/testlevel3/level3tab3.test_out b/tests/testlevel3/level3tab3.test_out new file mode 100644 index 0000000..32cd279 --- /dev/null +++ b/tests/testlevel3/level3tab3.test_out @@ -0,0 +1,8 @@ +t[0] = 8 +t[1] = 4 +t[2] = 6 +t[3] = 2 +t[4] = 5 +t[5] = 1 +t[6] = 3 +t[7] = 7 diff --git a/tests/testlevel3/level3tab3.vsl b/tests/testlevel3/level3tab3.vsl new file mode 100644 index 0000000..11f7b92 --- /dev/null +++ b/tests/testlevel3/level3tab3.vsl @@ -0,0 +1,19 @@ +FUNC VOID main() { + INT i, t[8],x + i := 0 + WHILE 8-i DO { + READ x + t[i] := x + i:= i+1 + } DONE + i := 0 + WHILE 8-i DO { + PRINT "t[",i,"] = ",t[i],"\n" + i:= i+1 + } DONE + } + + + + + diff --git a/tests/testlevel3/level3tab4.test_in b/tests/testlevel3/level3tab4.test_in new file mode 100644 index 0000000..86cf775 --- /dev/null +++ b/tests/testlevel3/level3tab4.test_in @@ -0,0 +1,9 @@ +7 +6 +5 +1 +2 +3 +4 +9 + diff --git a/tests/testlevel3/level3tab4.test_out b/tests/testlevel3/level3tab4.test_out new file mode 100644 index 0000000..82d205e --- /dev/null +++ b/tests/testlevel3/level3tab4.test_out @@ -0,0 +1 @@ +Tableau de taille 8 = [7,6,5,1,2,3,4,9] diff --git a/tests/testlevel3/level3tab4.vsl b/tests/testlevel3/level3tab4.vsl new file mode 100644 index 0000000..019fcf8 --- /dev/null +++ b/tests/testlevel3/level3tab4.vsl @@ -0,0 +1,24 @@ +PROTO VOID printtab(s,t[]) + +FUNC VOID main() { + INT i, t[8],x + i := 0 + WHILE 8-i DO { + READ x + t[i] := x + i:= i+1 + } DONE + printtab(8,t) +} + +FUNC VOID printtab(size,t[]) { + INT i + PRINT "Tableau de taille ", size," = [" + i := 0 + WHILE size-i DO { + IF i THEN PRINT "," FI + PRINT t[i] + i:= i+1 + } DONE + PRINT "]\n" + } diff --git a/tests/testlevel3/level3tab5.test_in b/tests/testlevel3/level3tab5.test_in new file mode 100644 index 0000000..3bde195 --- /dev/null +++ b/tests/testlevel3/level3tab5.test_in @@ -0,0 +1,3 @@ +10 +20 + diff --git a/tests/testlevel3/level3tab5.test_out b/tests/testlevel3/level3tab5.test_out new file mode 100644 index 0000000..7981842 --- /dev/null +++ b/tests/testlevel3/level3tab5.test_out @@ -0,0 +1,3 @@ +entrezno :0 entrezno :1 Tableau de taille 2 = [10,20] +Main: Tableau de taille 2 = [10,20] +Fini \ No newline at end of file diff --git a/tests/testlevel3/level3tab5.vsl b/tests/testlevel3/level3tab5.vsl new file mode 100644 index 0000000..b29a961 --- /dev/null +++ b/tests/testlevel3/level3tab5.vsl @@ -0,0 +1,37 @@ +PROTO VOID readprinttab(s,t[]) + +FUNC VOID main() { + INT i,s,t[2] + s := 2 + readprinttab(s,t) + PRINT "Main: Tableau de taille ",s," = [" + i := 0 + WHILE s-i DO { + IF i THEN PRINT "," FI + PRINT t[i] + i:= i+1 + } + DONE + PRINT "]\n" + PRINT "Fini" +} + +FUNC VOID readprinttab(size,t[]) { + INT i + i := 0 + WHILE size-i DO { + PRINT "entrezno :",i," " + READ t[i] + i:= i+1 + } + DONE + PRINT "Tableau de taille ",size," = [" + i := 0 + WHILE size-i DO { + IF i THEN PRINT "," FI + PRINT t[i] + i:= i+1 + } + DONE + PRINT "]\n" +} diff --git a/tests/testlevel4/level4diverge.vsl b/tests/testlevel4/level4diverge.vsl new file mode 100644 index 0000000..b3486c2 --- /dev/null +++ b/tests/testlevel4/level4diverge.vsl @@ -0,0 +1,5 @@ +FUNC VOID main() { + PRINT "Toto" + WHILE 1 DO { INT x + x := 1 } DONE + } diff --git a/tests/testlevel4/level4t1.test_out b/tests/testlevel4/level4t1.test_out new file mode 100644 index 0000000..923de2b --- /dev/null +++ b/tests/testlevel4/level4t1.test_out @@ -0,0 +1 @@ +Et voila: 0001 \ No newline at end of file diff --git a/tests/testlevel4/level4t1.vsl b/tests/testlevel4/level4t1.vsl new file mode 100644 index 0000000..3ae06bf --- /dev/null +++ b/tests/testlevel4/level4t1.vsl @@ -0,0 +1,18 @@ +FUNC VOID main() +{ + INT i,j,k,l + i := 0 + j := 0 + k := 0 + l := 0 + { INT i,j,k + l := 1 + { INT i,j + k:= 2 + { INT i + j:= 3 + } + } + } + PRINT "Et voila: ", i,j,k,l +} diff --git a/tests/testlevel4/level4testcarre.test_out b/tests/testlevel4/level4testcarre.test_out new file mode 100644 index 0000000..b62b65d --- /dev/null +++ b/tests/testlevel4/level4testcarre.test_out @@ -0,0 +1,2 @@ + +5^2 + 4^2 + 3^2 + 2^2 + 1^2 = 55 diff --git a/tests/testlevel4/level4testcarre.vsl b/tests/testlevel4/level4testcarre.vsl new file mode 100644 index 0000000..5821885 --- /dev/null +++ b/tests/testlevel4/level4testcarre.vsl @@ -0,0 +1,28 @@ +FUNC VOID main() +{ INT n,i,s + + n := 5 + s := 0 + i := n + + WHILE i + DO + { s := s + i*i + i := i - 1 + } + DONE + + PRINT "\n" + + i := n + WHILE i-1 + DO + { PRINT i, "^2 + " + i := i - 1 + } + DONE + + PRINT "1^2 = ", s, "\n" + +} + diff --git a/tests/testlevel4/level4testfact.test_out b/tests/testlevel4/level4testfact.test_out new file mode 100644 index 0000000..6da7281 --- /dev/null +++ b/tests/testlevel4/level4testfact.test_out @@ -0,0 +1,11 @@ +f(0) = 1 +f(1) = 1 +f(2) = 2 +f(3) = 6 +f(4) = 24 +f(5) = 120 +f(6) = 720 +f(7) = 5040 +f(8) = 40320 +f(9) = 362880 +f(10) = 3628800 diff --git a/tests/testlevel4/level4testfact.vsl b/tests/testlevel4/level4testfact.vsl new file mode 100644 index 0000000..034140c --- /dev/null +++ b/tests/testlevel4/level4testfact.vsl @@ -0,0 +1,32 @@ +PROTO INT fact(k) +FUNC VOID main() +{ + INT i, t[11] + i := 0 + + WHILE 11 -i + DO + { + t[i] := fact(i) + i := i+1 + } + DONE + i := 0 + WHILE 11 -i + DO + { + PRINT "f(", i, ") = ", t[i], "\n" + i := i+1 + } + DONE +} + +FUNC INT fact(n) +{ + IF n + THEN + RETURN n* fact(n-1) + ELSE + RETURN 1 + FI +} \ No newline at end of file diff --git a/tests/testlevel4/level4testfact2.test_out b/tests/testlevel4/level4testfact2.test_out new file mode 100644 index 0000000..6da7281 --- /dev/null +++ b/tests/testlevel4/level4testfact2.test_out @@ -0,0 +1,11 @@ +f(0) = 1 +f(1) = 1 +f(2) = 2 +f(3) = 6 +f(4) = 24 +f(5) = 120 +f(6) = 720 +f(7) = 5040 +f(8) = 40320 +f(9) = 362880 +f(10) = 3628800 diff --git a/tests/testlevel4/level4testfact2.vsl b/tests/testlevel4/level4testfact2.vsl new file mode 100644 index 0000000..6f9bdee --- /dev/null +++ b/tests/testlevel4/level4testfact2.vsl @@ -0,0 +1,35 @@ +PROTO INT fact(k) +FUNC VOID main() +{ + INT i, t[11] + i := 0 + + WHILE 11 -i + DO + { + t[i] := fact(i) + i := i+1 + } + DONE + i := 0 + WHILE 11 -i + DO + { + PRINT "f(", i, ") = ", t[i], "\n" + i := i+1 + } + DONE +} + +FUNC INT fact(n) +{ + INT res + IF n + THEN + res := n* fact(n-1) + ELSE + res := 1 + FI + RETURN res +} + diff --git a/tests/testlevel4/level4testhanoi.test_out b/tests/testlevel4/level4testhanoi.test_out new file mode 100644 index 0000000..1d1a6de --- /dev/null +++ b/tests/testlevel4/level4testhanoi.test_out @@ -0,0 +1,29 @@ + + Hanoi avec 3 disques + +Deplacer un disque de 1 a 3 +Deplacer un disque de 1 a 2 +Deplacer un disque de 3 a 2 +Deplacer un disque de 1 a 3 +Deplacer un disque de 2 a 1 +Deplacer un disque de 2 a 3 +Deplacer un disque de 1 a 3 + + +Hanoi avec 4 disques + +Deplacer un disque de 1 a 2 +Deplacer un disque de 1 a 3 +Deplacer un disque de 2 a 3 +Deplacer un disque de 1 a 2 +Deplacer un disque de 3 a 1 +Deplacer un disque de 3 a 2 +Deplacer un disque de 1 a 2 +Deplacer un disque de 1 a 3 +Deplacer un disque de 2 a 3 +Deplacer un disque de 2 a 1 +Deplacer un disque de 3 a 1 +Deplacer un disque de 2 a 3 +Deplacer un disque de 1 a 2 +Deplacer un disque de 1 a 3 +Deplacer un disque de 2 a 3 diff --git a/tests/testlevel4/level4testhanoi.vsl b/tests/testlevel4/level4testhanoi.vsl new file mode 100644 index 0000000..5093f52 --- /dev/null +++ b/tests/testlevel4/level4testhanoi.vsl @@ -0,0 +1,30 @@ +PROTO INT hanoi(n,delatour,alatour,parlatour) + +FUNC VOID main() +{ + INT ndisque,a + + ndisque := 3 + PRINT "\n Hanoi avec ", ndisque, " disques\n\n" + a := hanoi(ndisque,1,3,2) + + ndisque := 4 + PRINT "\n\nHanoi avec ", ndisque, " disques\n\n" + a := hanoi(ndisque,1,3,2) +} + + +FUNC INT hanoi(n,delatour,alatour,parlatour) +{ + INT b + IF n + THEN + { + b := hanoi( n-1, delatour, parlatour, alatour ) + PRINT "Deplacer un disque de ",delatour," a ",alatour,"\n" + b := hanoi( n-1, parlatour, alatour, delatour ) + } + FI + RETURN 1 +} + diff --git a/tests/testlevel4/level4testheap.test_in b/tests/testlevel4/level4testheap.test_in new file mode 100644 index 0000000..a064e58 --- /dev/null +++ b/tests/testlevel4/level4testheap.test_in @@ -0,0 +1,11 @@ +5 +20 +15 +10 +4 +8 +13 +19 +30 +18 + diff --git a/tests/testlevel4/level4testheap.test_out b/tests/testlevel4/level4testheap.test_out new file mode 100644 index 0000000..5827830 --- /dev/null +++ b/tests/testlevel4/level4testheap.test_out @@ -0,0 +1,21 @@ + + Entrer le0eme: i=1 j=5 + Entrer le1eme: i=2 j=20 + Entrer le2eme: i=3 j=15 + Entrer le3eme: i=4 j=10 + Entrer le4eme: i=5 j=4 + Entrer le5eme: i=6 j=8 + Entrer le6eme: i=7 j=13 + Entrer le7eme: i=8 j=19 + Entrer le8eme: i=9 j=30 + Entrer le9eme: i=10 j=18 + t[0] = 4 + t[1] = 5 + t[2] = 8 + t[3] = 10 + t[4] = 13 + t[5] = 15 + t[6] = 18 + t[7] = 19 + t[8] = 20 + t[9] = 30 \ No newline at end of file diff --git a/tests/testlevel4/level4testheap.vsl b/tests/testlevel4/level4testheap.vsl new file mode 100644 index 0000000..d291d59 --- /dev/null +++ b/tests/testlevel4/level4testheap.vsl @@ -0,0 +1,122 @@ +PROTO INT plusgrandstrict(n,m) +PROTO INT plusgrand(n,m) +PROTO VOID heapsort(t[], n) + +// Ce programme lit un tableau de 10 entiers et imprime +// le tableau trie par heapsort. +//===================================================== +FUNC VOID main() +{ + INT a[10], i, j + + i := 0 + WHILE 10-i DO + { + PRINT "\n Entrer le",i,"eme: " + READ j + a[i] := j + i := i+1 + PRINT " i=", i, " j=",j + } + DONE + heapsort(a,10) + i := 0 + WHILE 10-i DO + { + PRINT "\n t[",i,"] = ",a[i] + i:= i+1 + } + DONE +} + + +// Implementation du heapsort +//=========================== +FUNC VOID heapsort(t[], n ) // n: nombre d'elements a trier +{ + INT l,r,j,s, test + + l := n/2+1 + r := n + + WHILE plusgrand(r,2) DO + { + IF plusgrandstrict(l,1) + THEN // agrandissement t[l..r] -> t[l-1..r] heap + { + l := l-1 + j := l + } + ELSE // selection : t[0] est le + grand et echange avec t[r-1] + // rearrangement de t[0..r-2] + { + INT ex + ex := t[0] + t[0] := t[r-1] + t[r-1] := ex + r := r-1 + j := 1 + } + FI + s := t[j-1] + test := plusgrand(r, 2*j) + WHILE test DO + { + INT k + k := 2*j // indice du premier fils de t[~j] + // on choisit le plus grand des deux + IF plusgrandstrict(r,k)*plusgrandstrict(t[k], t[k-1]) THEN k:=k+1 FI + // si le plus grand des deux est plus grand que s on echange avec s + IF plusgrandstrict(t[k-1],s) + THEN + { + t[j-1] := t[k-1] + j := k + test := plusgrand(r, 2*j) + } + ELSE test := 0 // une facon de faire un break + FI + } + DONE + t[j-1] := s + } + DONE +} + +// fonctions de comparaison entre entiers +//======================================= +FUNC INT plusgrandstrict(n,m ) +{ + INT continue, nn, mm + + continue := n*m + nn := n + mm := m + WHILE continue + DO + { + mm := mm-1 + nn := nn-1 + continue := nn*mm + } + DONE + IF nn THEN RETURN 1 ELSE RETURN 0 FI +} + +FUNC INT plusgrand(n,m ) +{ + INT continue, nn, mm + + continue := n*m + nn := n + mm := m + WHILE continue + DO + { + mm := mm-1 + nn := nn-1 + continue := nn*mm + } + DONE + IF nn THEN RETURN 1 ELSE IF mm THEN RETURN 0 ELSE RETURN 1 FI FI +} diff --git a/tests/testlevel4/level4testtri.test_in b/tests/testlevel4/level4testtri.test_in new file mode 100644 index 0000000..8393061 --- /dev/null +++ b/tests/testlevel4/level4testtri.test_in @@ -0,0 +1,11 @@ +10 +15 +12 +18 +17 +19 +13 +12 +11 +11 + diff --git a/tests/testlevel4/level4testtri.test_out b/tests/testlevel4/level4testtri.test_out new file mode 100644 index 0000000..8e5539b --- /dev/null +++ b/tests/testlevel4/level4testtri.test_out @@ -0,0 +1,21 @@ + + Entrer le 0eme: + Entrer le 1eme: + Entrer le 2eme: + Entrer le 3eme: + Entrer le 4eme: + Entrer le 5eme: + Entrer le 6eme: + Entrer le 7eme: + Entrer le 8eme: + Entrer le 9eme: + t[0] = 10 + t[1] = 11 + t[2] = 11 + t[3] = 12 + t[4] = 12 + t[5] = 13 + t[6] = 15 + t[7] = 17 + t[8] = 18 + t[9] = 19 \ No newline at end of file diff --git a/tests/testlevel4/level4testtri.vsl b/tests/testlevel4/level4testtri.vsl new file mode 100644 index 0000000..a9ce8d4 --- /dev/null +++ b/tests/testlevel4/level4testtri.vsl @@ -0,0 +1,80 @@ +PROTO INT plusgrandstrict(n,m) +PROTO VOID naivesort(t[], index) + +// Ce programme lit un tableau de 10 entiers et imprime +// le tableau trie. Illustre le passage de tableaux en parametres +//=============================================================== +FUNC VOID main() +{ + INT a[10], i, j + + i := 0 + WHILE 10-i DO + { + PRINT "\n Entrer le ",i,"eme: " + READ j + a[i] := j + i := i+1 + } + DONE + naivesort(a,9) + i := 0 + WHILE 10-i DO + { + PRINT "\n t[",i,"] = ",a[i] + i:= i+1 + } + DONE +} + + +// Tri naif: cherche le +grand elem du tableau et le met +// a la fin. Recommence avec le sous tableau terminant a index-1 +//============================================================== +FUNC VOID naivesort(t[], index ) +{ + INT max , maxpos, i + + IF index THEN // il y a au moins deux elements + { + max := t[index] + i:= index + maxpos := index + + WHILE i+1 DO + { + IF plusgrandstrict(t[i], max) THEN + { + max := t[i] + maxpos := i + } + FI + i := i-1 + } + DONE + t[maxpos] := t[index] + t[index] := max + naivesort(t,index-1) + } + FI +} + +// fonction de comparaison entre entiers +//====================================== +FUNC INT plusgrandstrict(n,m ) +{ + INT continue, nn, mm + + continue := n*m + nn := n + mm := m + WHILE continue + DO + { + mm := mm-1 + nn := nn-1 + continue := nn*mm + } + DONE + IF nn THEN RETURN 1 ELSE RETURN 0 FI +} \ No newline at end of file diff --git a/tests/testlevelerror/test_decl_scope.vsl b/tests/testlevelerror/test_decl_scope.vsl new file mode 100644 index 0000000..ac8029e --- /dev/null +++ b/tests/testlevelerror/test_decl_scope.vsl @@ -0,0 +1,10 @@ +FUNC INT main() { + { + INT i + i := 3 + PRINT i + } + PRINT i + RETURN 0 +} + diff --git a/tests/testlevelerror/test_decl_scope2.vsl b/tests/testlevelerror/test_decl_scope2.vsl new file mode 100644 index 0000000..7adb651 --- /dev/null +++ b/tests/testlevelerror/test_decl_scope2.vsl @@ -0,0 +1,11 @@ +FUNC VOID f() { + INT i + i := 2 +} + +FUNC INT main() { + f() + PRINT i + RETURN 0 +} + diff --git a/tests/testlevelerror/test_decl_scope3.vsl b/tests/testlevelerror/test_decl_scope3.vsl new file mode 100644 index 0000000..594854b --- /dev/null +++ b/tests/testlevelerror/test_decl_scope3.vsl @@ -0,0 +1,7 @@ +PROTO VOID f(i) + +FUNC INT main() { + PRINT i + RETURN 0 +} + diff --git a/tests/testlevelerror/test_func_redecl.vsl b/tests/testlevelerror/test_func_redecl.vsl new file mode 100644 index 0000000..e5b2fd9 --- /dev/null +++ b/tests/testlevelerror/test_func_redecl.vsl @@ -0,0 +1,10 @@ +FUNC INT main() { + PRINT "a" + RETURN 0 +} + +FUNC INT main() { + PRINT "a" + RETURN 0 +} + diff --git a/tests/testlevelerror/test_incompat_proto.vsl b/tests/testlevelerror/test_incompat_proto.vsl new file mode 100644 index 0000000..1d29ac2 --- /dev/null +++ b/tests/testlevelerror/test_incompat_proto.vsl @@ -0,0 +1,12 @@ +PROTO VOID fact() + +FUNC INT main() { + INT i, j + RETURN 0 +} + +FUNC VOID fact(i) { + INT j + j := i +} + diff --git a/tests/testlevelerror/test_incompat_proto2.vsl b/tests/testlevelerror/test_incompat_proto2.vsl new file mode 100644 index 0000000..888aa7d --- /dev/null +++ b/tests/testlevelerror/test_incompat_proto2.vsl @@ -0,0 +1,10 @@ +PROTO VOID fact() + +FUNC INT main() { + INT i, j + RETURN 0 +} + +FUNC INT fact() { + RETURN 1 +} diff --git a/tests/testlevelerror/test_incompat_proto3.vsl b/tests/testlevelerror/test_incompat_proto3.vsl new file mode 100644 index 0000000..6f9e400 --- /dev/null +++ b/tests/testlevelerror/test_incompat_proto3.vsl @@ -0,0 +1,11 @@ +PROTO INT fact(t[], i) + +FUNC INT main() { + INT i, j + RETURN 0 +} + +FUNC INT fact(i, j) { + RETURN i +} + diff --git a/tests/testlevelerror/test_incompat_proto4.vsl b/tests/testlevelerror/test_incompat_proto4.vsl new file mode 100644 index 0000000..a24fa28 --- /dev/null +++ b/tests/testlevelerror/test_incompat_proto4.vsl @@ -0,0 +1,21 @@ +PROTO VOID f(i, j, t[], m, k[]) + +FUNC INT main() { + INT i, j + INT t1[3] + INT t2[2] + i := 0 + j := 1 + t1[0] := 4 + t1[1] := 5 + t1[2] := 6 + t2[0] := 9 + t2[1] := 10 + f(i, j, t1, i, t2) + RETURN 0 +} + +FUNC VOID f(i, j, t, m, k[]) { + PRINT i +} + diff --git a/tests/testlevelerror/test_incompat_proto5.vsl b/tests/testlevelerror/test_incompat_proto5.vsl new file mode 100644 index 0000000..5e1850a --- /dev/null +++ b/tests/testlevelerror/test_incompat_proto5.vsl @@ -0,0 +1,21 @@ +PROTO VOID f(i, j, t[], m, k[]) + +FUNC INT main() { + INT i, j + INT t1[3] + INT t2[2] + i := 0 + j := 1 + t1[0] := 4 + t1[1] := 5 + t1[2] := 6 + t2[0] := 9 + t2[1] := 10 + f(i, j, t1, i, t1) + RETURN 0 +} + +FUNC VOID f(i, j, t[], k[], l[]) { + PRINT i +} + diff --git a/tests/testlevelerror/test_invalid_assign.vsl b/tests/testlevelerror/test_invalid_assign.vsl new file mode 100644 index 0000000..193072e --- /dev/null +++ b/tests/testlevelerror/test_invalid_assign.vsl @@ -0,0 +1,8 @@ +FUNC INT main() { + INT i + INT t[2] + i := 1 + t := i + RETURN 0 +} + diff --git a/tests/testlevelerror/test_invalid_assign2.vsl b/tests/testlevelerror/test_invalid_assign2.vsl new file mode 100644 index 0000000..4524891 --- /dev/null +++ b/tests/testlevelerror/test_invalid_assign2.vsl @@ -0,0 +1,9 @@ +FUNC INT main() { + INT i + INT t[2] + t[0] := 1 + t[1] := 2 + i := t + RETURN 0 +} + diff --git a/tests/testlevelerror/test_invalid_call.vsl b/tests/testlevelerror/test_invalid_call.vsl new file mode 100644 index 0000000..3981cfa --- /dev/null +++ b/tests/testlevelerror/test_invalid_call.vsl @@ -0,0 +1,12 @@ +FUNC VOID f(i) { + INT j + j := i +} + +FUNC INT main() { + INT i + i := 0 + i := f(i) + RETURN 0 +} + diff --git a/tests/testlevelerror/test_invalid_call2.vsl b/tests/testlevelerror/test_invalid_call2.vsl new file mode 100644 index 0000000..6c71d8e --- /dev/null +++ b/tests/testlevelerror/test_invalid_call2.vsl @@ -0,0 +1,22 @@ +PROTO VOID f(i, j, t[], m, k[]) + +FUNC INT main() { + INT i, j, m + INT t1[3] + INT t2[2] + i := 0 + j := 1 + t1[0] := 4 + t1[1] := 5 + t1[2] := 6 + t2[0] := 9 + t2[1] := 10 + m := 3 + f(i, j, t1, m, m) + RETURN 0 +} + +FUNC VOID f(i, j, t[], m, k[]) { + PRINT i +} + diff --git a/tests/testlevelerror/test_invalid_call3.vsl b/tests/testlevelerror/test_invalid_call3.vsl new file mode 100644 index 0000000..fc43388 --- /dev/null +++ b/tests/testlevelerror/test_invalid_call3.vsl @@ -0,0 +1,21 @@ +PROTO VOID f(i, j, t[], m, k[]) + +FUNC INT main() { + INT i, j + INT t1[3] + INT t2[2] + i := 0 + j := 1 + t1[0] := 4 + t1[1] := 5 + t1[2] := 6 + t2[0] := 9 + t2[1] := 10 + f(i, j, t1, t2, t2) + RETURN 0 +} + +FUNC VOID f(i, j, t[], m, k[]) { + PRINT i +} + diff --git a/tests/testlevelerror/test_invalid_recursion.vsl b/tests/testlevelerror/test_invalid_recursion.vsl new file mode 100644 index 0000000..93b9d53 --- /dev/null +++ b/tests/testlevelerror/test_invalid_recursion.vsl @@ -0,0 +1,10 @@ +FUNC INT f(a) { + IF a THEN RETURN 0 + ELSE RETURN f(a-1) + FI +} + +FUNC INT main(){ + PRINT "La fonction f n est pas declaree avant sa premiere utilisation" + RETURN f(5) +} \ No newline at end of file diff --git a/tests/testlevelerror/test_invalid_return.vsl b/tests/testlevelerror/test_invalid_return.vsl new file mode 100644 index 0000000..8478973 --- /dev/null +++ b/tests/testlevelerror/test_invalid_return.vsl @@ -0,0 +1,12 @@ +FUNC INT f() { + INT t[1] + t[0] := 1 + RETURN t +} + +FUNC INT main() { + INT i + i := f() + RETURN 0 +} + diff --git a/tests/testlevelerror/test_undecl_func.vsl b/tests/testlevelerror/test_undecl_func.vsl new file mode 100644 index 0000000..e4a6581 --- /dev/null +++ b/tests/testlevelerror/test_undecl_func.vsl @@ -0,0 +1,6 @@ +FUNC INT main() { + INT i, j + j := func() + RETURN 0 +} + diff --git a/tests/testlevelerror/test_undecl_var.vsl b/tests/testlevelerror/test_undecl_var.vsl new file mode 100644 index 0000000..2ca0a92 --- /dev/null +++ b/tests/testlevelerror/test_undecl_var.vsl @@ -0,0 +1,6 @@ +FUNC INT main() { + INT i + j := i + RETURN 0 +} + diff --git a/tests/testlevelerror/test_var_redecl.vsl b/tests/testlevelerror/test_var_redecl.vsl new file mode 100644 index 0000000..2300190 --- /dev/null +++ b/tests/testlevelerror/test_var_redecl.vsl @@ -0,0 +1,8 @@ +FUNC INT main() { + INT i + INT i + i := 1 + PRINT i + RETURN 0 +} +