From ae1896278ef339934b8842660553d87cd2dd8f08 Mon Sep 17 00:00:00 2001 From: Not Zed Date: Thu, 23 Mar 2023 19:20:14 +1030 Subject: [PATCH] Initial import. --- Makefile | 36 + README | 2 + antlr4.make | 57 + build.xml | 65 + config.make.in | 14 + java.make | 425 ++++ maven.make | 87 + nbproject/build-impl.xml | 1866 +++++++++++++++++ nbproject/genfiles.properties | 8 + nbproject/project.properties | 105 + nbproject/project.xml | 16 + .../classes/au/notzed/scripta/AST.java | 467 +++++ .../classes/au/notzed/scripta/ASTBuilder.java | 244 +++ .../classes/au/notzed/scripta/ASTPrinter.java | 183 ++ .../classes/au/notzed/scripta/ASTVisitor.java | 108 + .../classes/au/notzed/scripta/Compiler.java | 108 + .../classes/au/notzed/scripta/Generator.java | 22 + src/notzed.scripta/classes/module-info.java | 21 + src/notzed.scripta/gen/ScriptA.g4 | 96 + src/notzed.scripta/gen/gen.make | 5 + 20 files changed, 3935 insertions(+) create mode 100644 Makefile create mode 100644 README create mode 100644 antlr4.make create mode 100644 build.xml create mode 100644 config.make.in create mode 100644 java.make create mode 100644 maven.make create mode 100644 nbproject/build-impl.xml create mode 100644 nbproject/genfiles.properties create mode 100644 nbproject/project.properties create mode 100644 nbproject/project.xml create mode 100644 src/notzed.scripta/classes/au/notzed/scripta/AST.java create mode 100644 src/notzed.scripta/classes/au/notzed/scripta/ASTBuilder.java create mode 100644 src/notzed.scripta/classes/au/notzed/scripta/ASTPrinter.java create mode 100644 src/notzed.scripta/classes/au/notzed/scripta/ASTVisitor.java create mode 100644 src/notzed.scripta/classes/au/notzed/scripta/Compiler.java create mode 100644 src/notzed.scripta/classes/au/notzed/scripta/Generator.java create mode 100644 src/notzed.scripta/classes/module-info.java create mode 100644 src/notzed.scripta/gen/ScriptA.g4 create mode 100644 src/notzed.scripta/gen/gen.make diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..e2dc638 --- /dev/null +++ b/Makefile @@ -0,0 +1,36 @@ + +dist_VERSION=0.0.99 +dist_NAME=compilerz +dist_EXTRA= \ + README \ + build.xml \ + nbproject/build-impl.xml \ + nbproject/genfiles.properties \ + nbproject/project.properties \ + nbproject/project.xml + +include config.make + +java_MODULES = \ + notzed.scripta + +# auto-generate the _COMMANDS variables +define install-bin= +$1_COMMANDS = $(notdir $(wildcard src/$1/$(TARGET)/bin/*)) +bin/$1/$(TARGET)/bin/%: src/$1/$(TARGET)/bin/% + install -D -t $$(@D) $$< +endef +$(foreach mod,$(java_MODULES),$(eval $(call install-bin,$(mod)))) + +include java.make + +asm = org.ow2.asm:asm:9.4 \ + org.ow2.asm:asm-util:9.4 \ + org.ow2.asm:asm-tree:9.4 \ + org.ow2.asm:asm-analysis:9.4 \ + org.ow2.asm:asm-commons:9.4 + +maven_central_JARS = $(asm) + +include antlr4.make +include maven.make diff --git a/README b/README new file mode 100644 index 0000000..f9057e1 --- /dev/null +++ b/README @@ -0,0 +1,2 @@ + +Expriments with antlr and asm. diff --git a/antlr4.make b/antlr4.make new file mode 100644 index 0000000..09e622a --- /dev/null +++ b/antlr4.make @@ -0,0 +1,57 @@ +# +# Copyright (C) 2023 Michael Zucchi +# +# This is the copyright for antlr4.make +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +# This processes antlr4 files. Include after java.make, before maven.make. + +# _ANTLR4 = list of grammar files without '.g4' extension. + +# They must be in src//gen/.g4 +# The sources are generated in the usual gen directory + +antlr4 = org.antlr:antlr4:4.12.0 \ + org.antlr:antlr4-runtime:4.12.0 \ + org.antlr:antlr-runtime:3.5.3 \ + org.antlr:ST4:4.3.4 \ + +maven_central_JARS += $(antlr4) + +antlr4_CLASSPATH=.lib/antlr4-4.12.0.jar \ + .lib/antlr4-runtime-4.12.0.jar \ + .lib/antlr-runtime-3.5.3.jar \ + .lib/ST4-4.3.4.jar + +dist_EXTRA+=antlr4.make + +define antlr4_targets= +$(if $($1-$2_ANTLR4PACKAGE),,$(error src/gen/$1/gen/gen.make: no $1-$2_ANTLR4PACKAGE defined)) +bin/status/$1-$2.antlr: src/$1/gen/$2.g4 + mkdir -p bin/gen/$1/gen bin/status + cd src/$1/gen && \ + $(JAVA) -cp $(subst $S,:,$(realpath $(antlr4_CLASSPATH))) \ + org.antlr.v4.Tool \ + -o ../../../bin/gen/$1/classes/$(subst .,/,$($1-$2_ANTLR4PACKAGE)) \ + -package $($1-$2_ANTLR4PACKAGE) \ + $($1-$2_ANTLR4FLAGS) \ + $2.g4 + touch $$@ +bin/status/$1.depjava: bin/status/$1-$2.antlr +endef + +#$(foreach m,$(java_MODULES),$(foreach g,$($m_ANTLR4),$(info $(call antlr4_targets,$m,$g)))) +$(foreach m,$(java_MODULES),$(foreach g,$($m_ANTLR4),$(eval $(call antlr4_targets,$m,$g)))) diff --git a/build.xml b/build.xml new file mode 100644 index 0000000..412f012 --- /dev/null +++ b/build.xml @@ -0,0 +1,65 @@ + + + + + + + + + + + Builds, tests, and runs the project compilerz. + + + diff --git a/config.make.in b/config.make.in new file mode 100644 index 0000000..eed42de --- /dev/null +++ b/config.make.in @@ -0,0 +1,14 @@ + +TARGET ?= linux-amd64 + +JAVA_HOME ?= /usr/local/jdk +JAVAFX_HOME ?= /usr/local/javafx-sdk + +JAVAMODPATH = $(JAVAFX_HOME)/lib .lib bin/$(TARGET)/lib +JAVACFLAGS = --source 19 + +JAVA ?= $(JAVA_HOME)/bin/java +JAVAC ?= $(JAVA_HOME)/bin/javac +JAR ?= $(JAVA_HOME)/bin/jar +JMOD ?= $(JAVA_HOME)/bin/jmod + diff --git a/java.make b/java.make new file mode 100644 index 0000000..ada3e80 --- /dev/null +++ b/java.make @@ -0,0 +1,425 @@ +# +# Copyright (C) 2019,2022 Michael Zucchi +# +# This is the copyright for java.make +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +# General purpose modular java makefile that supports native library +# compilation directly. Non-recrusve implementation. +# +# Uses metamake programming with some file conventions to implement +# auto-make-like features. + +# Define modules +# -------------- +# java_MODULES list of java modules to compile. The sources must +# exist in src//classes. Resource files are +# stored in src//classes. Source-code +# generators must exist in src//gen. Native +# libraries must exist in src//jni. + +# native_MODULES list of native-only "modules". + + +# Global variables + +# JAVA_HOME location of jdk. +# JAVAC java compiler to use. Default is 'javac' on the path. +# JAVACFLAGS javac flags applied to all invocations. +# JAR jar command. +# JARFLAGS jar flags +# JMOD jmod command. +# JMODFLAGS jmod flags. +# JAVAFLAGS java flags for run targets + +# Module specific variables + +# _JDEPMOD Lists modules which this one depends on. + +# _JAVACFLAGS Extra module-specific flags for each command. +# _JARFLAGS +# _JMODFLAGS + +# all paths are relative to the root package name + +# _JAVA Java sources. If not set it is found from src//classes/(*.java) +# _RESOURCES .jar resources. If not set it is found from src//classes/(not *.java) +# _JAVA_GENERATED Java generated sources. +# _RESOURCES_GENERATED Java generated sources. + +# Variables for use in fragments + +# gen.make and jni.make can additionally make use of these variables + +# _gendir Location for files used in Java generation process (per project). +# _genjavadir Location where _JAVA_GENERATED .java files will be created (per project). +# _objdir Location for c objects (per target). +# _incdir Location for output includes, .jmod staging. +# _libdir Location for output libraries, .jmod staging. May point to _bindir. +# _bindir Location for output commands, .jmod staging. + +# Define libraries +# ---------------- + +# Each module can define one or more native libraries. + +# These are compiled after the java sources have been compiled as that +# process also generates any native binding headers. + +# _NATIVE_LIBRARIES list of libraries to build. +# library names match System.loadLibrary(). + +# Global variables + +# _LDFLAGS +# _LDLIBS +# _CPPFLAGS +# _CFLAGS +# _CC +# _CXXFLAGS +# _CXX +# SO shared library suffix +# LIB shared library prefix + +# Utility functions +# +# $(call library-path,,) will resolve to the library file name. + +# Per library variables. + +# _SOURCES .c source files for library. Paths are relative to src//native. +# _CXXSOURCES .c source files for library. Paths are relative to src//native. +# _HEADERS header files for install/jmod +# _COMMANDS commands/bin/scripts for install/jmod + +# _LDFLAGS link flags +# _LIBADD extra objects to add to link line +# _LDLIBS link libraries +# _CPPFLAGS c and c++ pre-processor flags. "-Isrc//jni -Ibin/include/" is implicit. +# _CCFLAGS c compiler flags +# _CXXFLAGS c++ compiler flags + +# _DEPENDENCIES A list of other objects on which this library depends before linking. + +# .c and .cc files have dependencies automatically generated + +# Targets +# ------- + +# make gen only generate java sources +# make clean rm -rf bin +# make dist create dist tar in bin/ +# make | make jar make all jars and jmods + +# Outputs +# ------- + +# All intermediate and output files are written to bin/ + +# This layout is enforced by javac +# bin/include// .h files from javac -h +# bin/modules// .class files from javac + +# This layout is convenient for netbeans +# bin/gen//gen/ .c, exe files for generator free use +# bin/gen//classes/ .java files from generator _JAVA_GENERATED + +# Working files +# bin/status/ marker files for makefile + +# bin///lib .so librareies for jmod _LIBRARIES = libname +# bin///obj .o, .d files for library _SOURCES +# bin///include .h files for jmod _HEADERS +# bin///.jmod .jmod module + +# Output files +# bin//lib/ modular jar files and shared libraries for GNU/linux dev +# bin//include/ header files for exported shared libraries +# bin//bin/ shared libraries for microsoft dev +# bin//jmods/ jmod files for 'jlink' use. + +# ###################################################################### + +all_MODULES = $(java_MODULES) $(native_MODULES) + +E:= +S:=$(E) $(E) +SO=$($(TARGET)_SO) +LIB=$($(TARGET)_LIB) + +# Define some useful variables before including fragments +define common_variables= +$1_gendir:=bin/gen/$1/gen +$1_genjavadir:=bin/gen/$1/classes +$1_objdir:=bin/$1/$(TARGET)/obj +$1_incdir:=bin/$1/$(TARGET)/include +$1_libdir:=$$(if $$(filter windows-%,$(TARGET)),bin/$1/$(TARGET)/bin,bin/$1/$(TARGET)/lib) +$1_bindir:=bin/$1/$(TARGET)/bin +endef + +define java_variables= +ifndef $1_JAVA +$1_JAVA := $$(shell cd src/$1/classes && find * -type f -name '*.java') +endif +ifndef $1_RESOURCES +$1_RESOURCES := $$(shell cd src/$1/classes && find * -type f \! -name '*.java') +endif +endef + +java_libdir:=$(if $(filter windows-%,$(TARGET)),bin/$(TARGET)/bin,bin/$(TARGET)/lib) +java_bindir:=bin/$(TARGET)/bin +java_jardir:=bin/$(TARGET)/lib +java_incdir:=bin/$(TARGET)/include +java_jmoddir:=bin/$(TARGET)/jmods + +$(foreach module,$(java_MODULES) $(native_MODULES),$(eval $(call common_variables,$(module)))) +$(foreach module,$(java_MODULES),$(eval $(call java_variables,$(module)))) + +# ###################################################################### + +all: +jar: +gen: + +.PHONY: all clean jar gen $(java_MODULES) dist +clean: + rm -rf bin + +# dist things +dist_TAR = bin/$(dist_NAME)-$(dist_VERSION).tar.gz +dist_FILES = config.make.in java.make Makefile src $(dist_EXTRA) + +# Gen is things that go into the jar (sources and resources) +include $(wildcard $(all_MODULES:%=src/%/gen/gen.make)) +# Native is things that go into the sdk/jmod +include $(wildcard $(all_MODULES:%=src/%/native/native.make)) + +# ###################################################################### + +# create module depencies +# variables: +# _sdk is the target location of an expanded 'sdk' for this module +# it resides in a common location bin// +# _jmod is the target location of a staging area for jmod files +# is resides in a per-module lcoation bin/// +# _java is all the targets that will cause the invocation of javac +# it includes the module source, generated sources, and sentinals for generated sources + +# targets: +# bin/status/.depjava marks all source/generated sources are ready/updated +# bin/status/.depjar all compiled class files and resources are ready/updated +# bin/status/.sdk all files are available in bin/ as if it was an installed image + +define module_vars= +$1_sdk := $(addprefix $(java_bindir)/,$($1_COMMANDS)) $(addprefix $(java_libdir)/,$($1_LIBRARIES)) $($1_NATIVE_LIBRARIES:%=$(java_libdir)/lib%.so) +$1_jmod := $(addprefix $($1_bindir)/,$($1_COMMANDS)) $(addprefix $($1_libdir)/,$($1_LIBRARIES)) $($1_NATIVE_LIBRARIES:%=$($1_libdir)/lib%.so) +$1_java :=$($1_JAVA:%=src/$1/classes/%) $($1_JAVA_GENERATED:%=$($1_genjavadir)/%) +$1_resources:= $($1_RESOURCES:%=bin/modules/$1/%) $($1_RESOURCES_GENERATED:%=bin/modules/$1/%) +$1_depjava := $($1_API:%=bin/status/$1-%.export) $(patsubst %,bin/status/%.classes, $(filter $($1_JDEPMOD),$(java_MODULES))) + +#ifneq ("$$(strip $$($1_java) $$($1_depjava))", "") +bin/status/$1.depjava: $$($1_java) $$($1_depjava) + @install -d $$(@D) + touch $$@ +bin/status/$1.depjar: bin/status/$1.classes $$($1_resources) + @install -d $$(@D) + touch $$@ +bin/status/$1.depmod: bin/status/$1.classes $$($1_resources) $$($1_jmod) + @install -d $$(@D) + touch $$@ +bin/status/$1.sdk: $(java_jardir)/$1.jar +jar: $(java_jardir)/$1.jar +gen: bin/status/$1.depjava +$1 all: $(java_jardir)/$1.jar $(java_jmoddir)/$1.jmod +#else +# acutally not sure here? +#$1 all: bin/status/$1.sdk +#endif + +$1-sdk sdk: bin/status/$1.sdk + +bin/status/$1.sdk: $$($1_sdk) $$($1_jmod) + @install -d $$(@D) + touch $$@ + +endef + +#$(foreach m,$(all_MODULES),$(info $(call module_vars,$m))) +$(foreach m,$(all_MODULES),$(eval $(call module_vars,$m))) + +# ###################################################################### +# notzed.nativez export-api +# ###################################################################### + +define api_targets= +bin/status/$1-$2.export: src/$1/gen/$2.api src/$1/gen/$2.h +bin/status/$1-$2.export: + mkdir -p bin/gen/$1/gen bin/status + $(NATIVEZ_HOME)/bin/export-api \ + -w bin/gen/$1/gen -d bin/gen/$1/classes $($1_APIFLAGS) $($1_$2_APIFLAGS) src/$1/gen/$2.api + touch $$@ + +bin/status/$1-$2.export.d: + @$(NATIVEZ_HOME)/bin/export-api -M -MT "$$(@:.d=) $$@" -MF $$@ \ + -w bin/gen/$1/gen -d bin/gen/$1/classes $($1_APIFLAGS) $($1_$2_APIFLAGS) src/$1/gen/$2.api 2>/dev/null + +$(if $(filter clean dist gen,$(MAKECMDGOALS)),,-include bin/status/$1-$2.export.d) +endef + +$(foreach m,$(all_MODULES),$(foreach a,$($m_API),$(eval $(call api_targets,$m,$a)))) + +# ###################################################################### +# Java +# ###################################################################### + +# Build targets for java modules + +define java_targets= + +# Create (modular) jar +$(java_jardir)/$1.jar: bin/status/$1.depjar + @install -d $$(@D) + $(JAR) cf $$@ \ + $(JARFLAGS) $$($(1)_JARFLAGS) \ + -C bin/modules/$(1) . + +# Create a jmod +$(java_jmoddir)/$1.jmod: bin/status/$1.depmod + rm -f $$@ + @install -d $$(@D) + $$(JMOD) create \ + $$(JMODFLAGS) $$($(1)_JMODFLAGS) \ + --target-platform $(TARGET) \ + --class-path bin/modules/$(1) \ + $$(if $$(wildcard bin/$(1)/$(TARGET)/include),--header-files bin/$(1)/$(TARGET)/include) \ + $$(if $$(wildcard src/$(1)/legal),--legal-notices src/$(1)/legal) \ + $$(if $$(wildcard bin/$(1)/$(TARGET)/bin),--cmds bin/$(1)/$(TARGET)/bin) \ + $$(if $$(wildcard bin/$(1)/$(TARGET)/lib),--libs bin/$(1)/$(TARGET)/lib) \ + $$@ + +# Create an IDE source zip, paths have to match --module-source-path +$(java_jardir)/$1-sources.zip: bin/status/$1.depjar + @install -d $$(@D) + $(JAR) -c -f $$@ -M \ + $$($1_JAVA:%=-C src/$1/classes %) \ + $$($1_JAVA_GENERATED:%=-C bin/gen/$1/classes %) + +# resources +bin/modules/$1/%: src/$1/classes/% + install -vD $$< $$@ +bin/modules/$1/%: $($1_gejavadir)/% + install -vD $$< $$@ + +# Compile module. +bin/status/$1.classes: bin/status/$1.depjava + @install -d $$(@D) + $(JAVAC) \ + --module-source-path "src/*/classes:bin/gen/*/classes" \ + $(if $(JAVAMODPATH),--module-path $(subst $(S),:,$(JAVAMODPATH))) \ + $(JAVACFLAGS) $($1_JAVACFLAGS) \ + -d bin/modules \ + -m $1 \ + $$($1_JAVA:%=src/$1/classes/%) \ + $$($1_JAVA_GENERATED:%=bin/gen/$1/classes/%) + touch $$@ +endef + +#$(foreach module,$(java_MODULES),$(info $(call java_targets,$(module)))) +$(foreach module,$(java_MODULES),$(eval $(call java_targets,$(module)))) + +# ###################################################################### + +# setup run-* targets +define run_targets= +run-$1/$2: bin/status/$1.sdk $($1_JDEPMOD:%=bin/status/%.sdk) + LD_LIBRARY_PATH=$(FFMPEG_HOME)/lib \ + $(JAVA) \ + $(if $(strip $(JAVAMODPATH) $($1_JAVAMODPATH)),--module-path $(subst $(S),:,$(strip $(JAVAMODPATH) $($1_JAVAMODPATH)))) \ + $(JMAINFLAGS) $($1_JMAINFLAGS) \ + -m $1/$2 \ + $(ARGV) +.PHONY: run-$1/$2 +endef + +#$(foreach module,$(java_MODULES),$(foreach main,$($(module)_JMAIN),$(info $(call run_targets,$(module),$(main))))) +$(foreach module,$(java_MODULES),$(foreach main,$($(module)_JMAIN),$(eval $(call run_targets,$(module),$(main))))) + +# ###################################################################### +# C and c++ native library support +# ###################################################################### + +define native_library= +# Rule for library $$2 in module $$1 +$2_OBJS = $(patsubst %.c, $($1_objdir)/%.o, $($2_SOURCES)) \ + $(patsubst %.cc, $($1_objdir)/%.o, $($2_CXXSOURCES)) +$2_SRCS = $(addprefix src/$1/native/,$($2_SOURCES)) +$2_SO = $($1_libdir)/$(LIB)$2$(SO) + +# Copy anything from staging area for jmods bin/module//* to sdk area bin//* +$(java_libdir)/%: $($(1)_libdir)/% + @install -d $$(@D) + ln -fs $$(abspath $$<) $$@ +$(java_bindir)/%: $($(1)_bindir)/% + @install -d $$(@D) + ln -fs $$(abspath $$<) $$@ +$(java_incdir)/%: $($(1)_incdir)/% + @install -d $$(@D) + ln -fs $$(abspath $$<) $$@ + +$($1_libdir)/$(LIB)$2$(SO): $$($2_OBJS) $($2_LIBADD) $($2_DEPENDENCIES) + @install -d $$(@D) + $($(TARGET)_CC) -o $$@ -shared \ + $($(TARGET)_LDFLAGS) $($2_LDFLAGS) $$($2_OBJS) $($2_LIBADD) $($(TARGET)_LDLIBS) $($2_LDLIBS) + +$($1_objdir)/%.o: src/$1/native/%.c + @install -d $$(@D) + $($(TARGET)_CC) -Isrc/$1/native -Ibin/include/$1 \ + $($(TARGET)_CPPFLAGS) $($2_CPPFLAGS) \ + $($(TARGET)_CFLAGS) $($2_CFLAGS) -c -o $$@ $$< + +$($1_objdir)/%.o: src/$1/native/%.cc + @install -d $$(@D) + $($(TARGET)_CXX) -Isrc/$1/native -Ibin/include/$1 \ + $($(TARGET)_CPPFLAGS) $($2_CPPFLAGS) \ + $($(TARGET)_CXXFLAGS) $($2_CXXFLAGS) -c -o $$@ $$< + +# auto-dependencies for c files +$($1_objdir)/%.d: src/$1/native/%.c + @install -d $$(@D) + @rm -f $$@ + @$($(TARGET)_CC) -MM -MT "$$(@:.d=.o) $$@" -Isrc/$1/jni -Ibin/include/$1 \ + $($(TARGET)_CPPFLAGS) $($2_CPPFLAGS) $$< -o $$@ 2>/dev/null + +# auto-dependencies for c++ files +$($1_objdir)/%.d: src/$1/native/%.cc + @install -d $$(@D) + @rm -f $$@ + @$($(TARGET)_CXX) -MM -MT "$$(@:.d=.o) $$@" -Isrc/$1/jni -Ibin/include/$1 \ + $($(TARGET)_CPPFLAGS) $($2_CPPFLAGS) $$< -o $$@ 2>/dev/null + +$(if $(filter clean dist gen,$(MAKECMDGOALS)),,-include $$($2_OBJS:.o=.d)) +endef + +#$(foreach module,$(all_MODULES),$(foreach library,$($(module)_NATIVE_LIBRARIES),$(info $(call native_library,$(module),$(library))))) +$(foreach module,$(all_MODULES),$(foreach library,$($(module)_NATIVE_LIBRARIES),$(eval $(call native_library,$(module),$(library))))) + +# ###################################################################### + +dist: + @install -d bin + tar cfz bin/$(dist_NAME)-$(dist_VERSION).tar.gz \ + --transform=s,^,$(dist_NAME)-$(dist_VERSION)/, \ + $(dist_FILES) diff --git a/maven.make b/maven.make new file mode 100644 index 0000000..c48227c --- /dev/null +++ b/maven.make @@ -0,0 +1,87 @@ +# +# Copyright (C) 2021 Michael Zucchi +# +# This is the copyright for maven.make +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +# This lets one download maven packages using simple automake syntax. + +# maven__URL = baseurl + +# Define the base url. maven_central_URL is already defined as +# maven_central_URL:=https://repo1.maven.org/maven2 + +# maven__JARS = group:artifact:version group:artifact:version ... + +# Define the artifacts required from the given maven repository. + +# That's it! + +# It defines several make targets. + +# make maven-init +# Will download the jar files. + +# make maven-verify +# Will download and check the signatures using gpg. The public key +# required for verification must be imported to gpg separately. + +# make distclean +# Will delete .lib + +# define maven central +maven_central_URL:=https://repo1.maven.org/maven2 +maven_repository_URL:=https://mvnrepository.com/artifact + +# find out what repositories the makefile defined +maven_REPOS=$(patsubst maven_%_URL,%,$(filter maven_%_URL,$(.VARIABLES))) + +dist_EXTRA+=maven.make + +# (group artifact version baseurl) +define maven_func= +$2_jar=.lib/$2-$3.jar +.lib/$2-$3.jar: + mkdir -p .lib + wget -O $$@ $(4)/$(subst .,/,$1)/$2/$3/$2-$3.jar || ( rm $$@ ; exit 1 ) +.lib/$2-$3.pom: + mkdir -p .lib + wget -O $$@ $(4)/$(subst .,/,$1)/$2/$3/$2-$3.pom || ( rm $$@ ; exit 1 ) +.lib-sources/$2-$3-sources.jar: + mkdir -p .lib-sources + wget -O $$@ $(4)/$(subst .,/,$1)/$2/$3/$2-$3-sources.jar || ( rm $$@ ; exit 1 ) +.lib-javadoc/$2-$3-javadoc.jar: + mkdir -p .lib-javadoc + wget -O $$@ $(4)/$(subst .,/,$1)/$2/$3/$2-$3-javadoc.jar || ( rm $$@ ; exit 1 ) +.lib/$2-$3.jar.asc: .lib/$2-$3.jar + wget -O $$@ $(4)/$(subst .,/,$1)/$2/$3/$2-$3.jar.asc + gpg --batch --verify $$@ $$< || ( rm $$@ ; echo "GPG verification failed, you may need to import the public key." ; exit 1 ) +maven-init: .lib/$2-$3.jar .lib-sources/$2-$3-sources.jar .lib-javadoc/$2-$3-javadoc.jar .lib/$2-$3.pom +maven-verify: .lib/$2-$3.jar.asc +endef + +maven-init: +maven-verify: + +.PHONY: maven-init maven-verify + +$(foreach repo,$(maven_REPOS),\ + $(foreach jar,$(maven_$(repo)_JARS), \ + $(eval $(call maven_func,$(word 1,$(subst :, ,$(jar))),$(word 2,$(subst :, ,$(jar))),$(word 3,$(subst :, ,$(jar))),$(maven_$(repo)_URL))))) + +distclean: + rm -rf .lib .lib-javadoc .lib-sources + diff --git a/nbproject/build-impl.xml b/nbproject/build-impl.xml new file mode 100644 index 0000000..74009e9 --- /dev/null +++ b/nbproject/build-impl.xml @@ -0,0 +1,1866 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +package netbeans; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.regex.Pattern; +import java.util.stream.Collectors; +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Task; + +public class CoalesceKeyvalue extends Task { + private String property; + + public void setProperty(String property) { + this.property = property; + } + + private String value; + + public void setValue(String value) { + this.value = value; + } + + private String valueSep; + + public void setValueSep(String valueSep) { + this.valueSep = valueSep; + } + + private String entrySep; + + public void setEntrySep(String entrySep) { + this.entrySep = entrySep; + } + + private String multiSep; + + public void setMultiSep(String multiSep) { + this.multiSep = multiSep; + } + + private String outSep; + + public void setOutSep(String outSep) { + this.outSep = outSep; + } + + @Override + public void execute() throws BuildException { + List<String> result = new ArrayList<>(); + Map<String, List<String>> module2Paths = new HashMap<>(); + + for (String entry : value.split(Pattern.quote(entrySep))) { + String[] keyValue = entry.split(Pattern.quote(valueSep), 2); + if (keyValue.length == 1) { + result.add(keyValue[0]); + } else { + module2Paths.computeIfAbsent(keyValue[0], s -> new ArrayList<>()) + .add(keyValue[1].trim()); + } + } + module2Paths.entrySet() + .stream() + .forEach(e -> result.add(e.getKey() + valueSep + e.getValue().stream().collect(Collectors.joining(multiSep)))); + getProject().setProperty(property, result.stream().collect(Collectors.joining(" " + entrySep))); + } + +} + + + + +package netbeans; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Task; + +public class ModsourceRegexp extends Task { + private String property; + + public void setProperty(String property) { + this.property = property; + } + + private String filePattern; + + public void setFilePattern(String filePattern) { + this.filePattern = filePattern; + } + + private String modsource; + + public void setModsource(String modsource) { + this.modsource = modsource; + } + + private List<String> expandGroup(String grp) { + List<String> exp = new ArrayList<>(); + String item = ""; + int depth = 0; + + for (int i = 0; i < grp.length(); i++) { + char c = grp.charAt(i); + switch (c) { + case '{': + if (depth++ == 0) { + continue; + } + break; + case '}': + if (--depth == 0) { + exp.add(item); + continue; + } + break; + case ',': + if (depth == 1) { + exp.add(item); + item = ""; + continue; + } + default: + break; + } + item = item + c; + } + return exp; + } + + private List<String> pathVariants(String spec) { + return pathVariants(spec, new ArrayList<>()); + } + + private List<String> pathVariants(String spec, List<String> res) { + int start = spec.indexOf('{'); + if (start == -1) { + res.add(spec); + return res; + } + int depth = 1; + int end; + for (end = start + 1; end < spec.length() && depth > 0; end++) { + char c = spec.charAt(end); + switch (c) { + case '{': depth++; break; + case '}': depth--; break; + } + } + String prefix = spec.substring(0, start); + String suffix = spec.substring(end); + expandGroup(spec.substring(start, end)).stream().forEach(item -> { + pathVariants(prefix + item + suffix, res); + }); + return res; + } + + private String toRegexp2(String spec, String filepattern, String separator) { + List<String> prefixes = new ArrayList<>(); + List<String> suffixes = new ArrayList<>(); + pathVariants(spec).forEach(item -> { + suffixes.add(item); + }); + String tail = ""; + String separatorString = separator; + if ("\\".equals(separatorString)) { + separatorString = "\\\\"; + } + if (filepattern != null && !Objects.equals(filepattern, tail)) { + tail = separatorString + filepattern; + } + return "([^" + separatorString +"]+)\\Q" + separator + "\\E(" + suffixes.stream().collect(Collectors.joining("|")) + ")" + tail; + } + + @Override + public void execute() throws BuildException { + getProject().setProperty(property, toRegexp2(modsource, filePattern, getProject().getProperty("file.separator"))); + } + +} + + + + +package netbeans; + +import java.io.File; +import java.util.Arrays; +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.types.selectors.BaseExtendSelector; + +public class ModuleInfoSelector extends BaseExtendSelector { + + @Override + public boolean isSelected(File basedir, String filename, File file) throws BuildException { + String extension = Arrays.stream(getParameters()) + .filter(p -> "extension".equals(p.getName())) + .map(p -> p.getValue()) + .findAny() + .get(); + return !new File(file, "module-info." + extension).exists(); + } + +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @{paths} + + + + + + + + + + + + @{paths} + + + + + + + + + + + + + + + + + + + + Must set src.dir + Must set src.gen.dir + Must set test.src.dir + Must set build.dir + Must set dist.dir + Must set build.modules.dir + Must set dist.javadoc.dir + Must set build.test.modules.dir + Must set build.test.results.dir + Must set build.classes.excludes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + No tests executed. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set JVM to use for profiling in profiler.info.jvm + Must set profiler agent JVM arguments in profiler.info.jvmargs.agent + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + No main class specified + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set run.class + + + + Must select one file in the IDE or set run.class + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set debug.class + + + + + Must select one file in the IDE or set debug.class + + + + + Must set fix.includes + + + + + + + + + + + This target only works when run from inside the NetBeans IDE. + + + + + + + + + Must select one file in the IDE or set profile.class + This target only works when run from inside the NetBeans IDE. + + + + + + + + + This target only works when run from inside the NetBeans IDE. + + + + + + + + + + + + + This target only works when run from inside the NetBeans IDE. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set run.class + + + + + + Must select some files in the IDE or set test.includes + + + + + Must select one file in the IDE or set run.class + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + Some tests failed; see details above. + + + + + + + + + Must select some files in the IDE or set test.includes + + + + Some tests failed; see details above. + + + + Must select some files in the IDE or set test.class + Must select some method in the IDE or set test.method + + + + Some tests failed; see details above. + + + + + Must select one file in the IDE or set test.class + + + + Must select one file in the IDE or set test.class + Must select some method in the IDE or set test.method + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/nbproject/genfiles.properties b/nbproject/genfiles.properties new file mode 100644 index 0000000..f0c9780 --- /dev/null +++ b/nbproject/genfiles.properties @@ -0,0 +1,8 @@ +build.xml.data.CRC32=78569814 +build.xml.script.CRC32=d88c472e +build.xml.stylesheet.CRC32=32069288@1.21 +# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. +# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. +nbproject/build-impl.xml.data.CRC32=78569814 +nbproject/build-impl.xml.script.CRC32=160900c8 +nbproject/build-impl.xml.stylesheet.CRC32=d1ebcf0f@1.21 diff --git a/nbproject/project.properties b/nbproject/project.properties new file mode 100644 index 0000000..31e3525 --- /dev/null +++ b/nbproject/project.properties @@ -0,0 +1,105 @@ +annotation.processing.enabled=true +annotation.processing.enabled.in.editor=false +annotation.processing.processors.list= +annotation.processing.run.all.processors=true +annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output +application.title=compilerz +application.vendor=notzed +build.classes.dir=${build.dir}/classes +build.classes.excludes=**/*.java,**/*.form +# This directory is removed when the project is cleaned: +build.dir=build +build.generated.dir=${build.dir}/generated +build.generated.sources.dir=${build.dir}/generated-sources +build.modules.dir=${build.dir}/modules +# Only compile against the classpath explicitly listed here: +build.sysclasspath=ignore +build.test.classes.dir=${build.dir}/test/classes +build.test.modules.dir=${build.dir}/test/modules +build.test.results.dir=${build.dir}/test/results +# Uncomment to specify the preferred debugger connection transport: +#debug.transport=dt_socket +debug.classpath=\ + ${run.classpath} +debug.modulepath=\ + ${run.modulepath} +debug.test.classpath=\ + ${run.test.classpath} +debug.test.modulepath=\ + ${run.test.modulepath} +# Files in build.classes.dir which should be excluded from distribution jar +dist.archive.excludes= +# This directory is removed when the project is cleaned: +dist.dir=dist +dist.javadoc.dir=${dist.dir}/javadoc +dist.jlink.dir=${dist.dir}/jlink +dist.jlink.output=${dist.jlink.dir}/compilerz +endorsed.classpath= +excludes= +file.reference.antlr4-runtime-4.12.0.jar=.lib/antlr4-runtime-4.12.0.jar +file.reference.asm-9.4.jar=.lib/asm-9.4.jar +includes=** +jar.compress=false +javac.classpath= +# Space-separated list of extra javac options +javac.compilerargs= +javac.deprecation=false +javac.external.vm=false +javac.modulepath=\ + ${file.reference.asm-9.4.jar}:\ + ${file.reference.antlr4-runtime-4.12.0.jar} +javac.processormodulepath= +javac.processorpath=\ + ${javac.classpath} +javac.source=19 +javac.target=19 +javac.test.classpath=\ + ${javac.classpath} +javac.test.modulepath=\ + ${javac.modulepath}:\ + ${build.modules.dir} +javac.test.processorpath=\ + ${javac.test.classpath} +javadoc.additionalparam= +javadoc.author=false +javadoc.encoding=${source.encoding} +javadoc.html5=false +javadoc.noindex=false +javadoc.nonavbar=false +javadoc.notree=false +javadoc.private=false +javadoc.reference.antlr4-runtime-4.12.0.jar=.lib-javadoc/antlr4-runtime-4.12.0-javadoc.jar +javadoc.splitindex=true +javadoc.use=true +javadoc.version=false +javadoc.windowtitle= +# The jlink additional root modules to resolve +jlink.additionalmodules= +# The jlink additional command line parameters +jlink.additionalparam= +jlink.launcher=true +jlink.launcher.name=compilerz +main.class=au.notzed.scripta.Compiler +platform.active=default_platform +project.license=gpl3-notzed +run.classpath= +# Space-separated list of JVM arguments used when running the project. +# You may also define separate properties like run-sys-prop.name=value instead of -Dname=value. +# To set system properties for unit tests define test-sys-prop.name=value: +run.jvmargs= +run.modulepath=\ + ${javac.modulepath}:\ + ${build.modules.dir} +run.test.classpath=\ + ${javac.test.classpath} +run.test.modulepath=\ + ${javac.test.modulepath}:\ + ${build.test.modules.dir} +source.encoding=UTF-8 +source.reference.antlr4-runtime-4.12.0.jar=.lib-sources/antlr4-runtime-4.12.0-sources.jar +src.dir=src +src.dir.path=classes +src.gen.dir=bin/gen +src.gen.dir.path=classes +test.src.dir=src +test.src.dir.path=tests diff --git a/nbproject/project.xml b/nbproject/project.xml new file mode 100644 index 0000000..4be5939 --- /dev/null +++ b/nbproject/project.xml @@ -0,0 +1,16 @@ + + + org.netbeans.modules.java.j2semodule + + + compilerz + + + + + + + + + + diff --git a/src/notzed.scripta/classes/au/notzed/scripta/AST.java b/src/notzed.scripta/classes/au/notzed/scripta/AST.java new file mode 100644 index 0000000..7756507 --- /dev/null +++ b/src/notzed.scripta/classes/au/notzed/scripta/AST.java @@ -0,0 +1,467 @@ +/* + * Copyright (C) 2023 Michael Zucchi + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package au.notzed.scripta; + +import java.util.List; +import java.util.Optional; + +public abstract class AST { + + public final int lineNo; + + // visit children how? + public abstract void accept(ASTVisitor av); + + public void visitChildren(ASTVisitor av) { + } + + public void accept(List list, ASTVisitor av) { + for (AST s: list) { + s.accept(av); + } + } + + public AST(int lineNo) { + this.lineNo = lineNo; + } + + enum ReferenceScope { + LOCAL, + GLOBAL, + PLAYER + } + + enum XUnaryOp { + NOP, // for + + NEG, + NOT, + } + + enum XBinaryOp { + // arithmetic + ADD, + SUB, + MUL, + DIV, + MOD, + // bitwise + LSR, + LSL, + ASR, + AND, + ORR, + XOR, + // compare + CLT, + CLE, + CGT, + CGE, + CEQ, + CNE, + // boolean + AAND, + OOR, + XXOR, + } + + public static class ScriptA extends AST { + List statements; + + public ScriptA(List statements) { + super(0); + this.statements = statements; + } + + @Override + public void accept(ASTVisitor av) { + accept(statements, av); + } + } + + public static class Statements extends AST { + List statements; + + public Statements(int lineNo, List statements) { + super(lineNo); + this.statements = statements; + } + + @Override + public void accept(ASTVisitor av) { + av.visit(this); + } + + @Override + public void visitChildren(ASTVisitor av) { + accept(statements, av); + } + + public static final Statements EMPTY = new Statements(0, List.of()); + } + + /* **** statements */ + public abstract static class Statement extends AST { + public Statement(int lineNo) { + super(lineNo); + } + } + + static class SIf extends Statement { + final Expression test; + final Statements then; + final Optional rest; + + public SIf(int lineNo, Expression test, Statements then) { + super(lineNo); + this.test = test; + this.then = then; + this.rest = Optional.empty(); + } + + public SIf(int lineNo, Expression test, Statements then, Statements rest) { + super(lineNo); + this.test = test; + this.then = then; + this.rest = Optional.of(rest); + } + + @Override + public void accept(ASTVisitor av) { + av.visit(this); + } + + @Override + public void visitChildren(ASTVisitor av) { + test.accept(av); + then.accept(av); + rest.ifPresent(r -> r.accept(av)); + } + } + + static class SWhile extends Statement { + final Expression test; + final Statements when; + + public SWhile(int lineNo, Expression test, Statements when) { + super(lineNo); + this.test = test; + this.when = when; + } + + @Override + public void accept(ASTVisitor av) { + av.visit(this); + } + + @Override + public void visitChildren(ASTVisitor av) { + test.accept(av); + when.accept(av); + } + } + + static class SDeclare extends Statement { + final XReference ref; + + public SDeclare(int lineNo, AST.XReference ref) { + super(lineNo); + this.ref = ref; + } + + @Override + public void accept(ASTVisitor av) { + av.visit(this); + } + + @Override + public void visitChildren(ASTVisitor av) { + ref.accept(av); + } + } + + static class SAssign extends Statement { + final XReference ref; + final Expression value; + + public SAssign(int lineNo, AST.XReference ref, AST.Expression value) { + super(lineNo); + this.ref = ref; + this.value = value; + + System.out.printf(" new assign %s = %s\n", ref, value); + } + + @Override + public void accept(ASTVisitor av) { + av.visit(this); + } + + @Override + public void visitChildren(ASTVisitor av) { + ref.accept(av); + value.accept(av); + } + } + + enum SBreakType { + CONTINUE, + BREAK, + } + + static class SBreak extends Statement { + SBreakType op; + Optional label; + + public SBreak(int lineNo, SBreakType op) { + super(lineNo); + this.op = op; + this.label = Optional.empty(); + } + + public SBreak(int lineNo, SBreakType op, String label) { + super(lineNo); + this.label = Optional.of(label); + this.op = op; + } + + @Override + public void accept(ASTVisitor av) { + av.visit(this); + } + } + + static class SReturn extends Statement { + Optional res; + + public SReturn(int lineNo) { + super(lineNo); + res = Optional.empty(); + } + + public SReturn(int lineNo, Expression res) { + super(lineNo); + this.res = Optional.of(res); + } + + @Override + public void accept(ASTVisitor av) { + av.visit(this); + } + + @Override + public void visitChildren(ASTVisitor av) { + res.ifPresent(r -> r.accept(av)); + } + } + + static class SCall extends Statement { + XCall call; + + public SCall(int lineNo, XCall call) { + super(lineNo); + this.call = call; + } + + @Override + public void accept(ASTVisitor av) { + av.visit(this); + } + + @Override + public void visitChildren(ASTVisitor av) { + call.accept(av); + } + } + + /* **** expressions */ + abstract static class Expression extends AST { + public Expression(int lineNo) { + super(lineNo); + } + } + + static class XUnary extends Expression { + XUnaryOp op; + Expression right; + + public XUnary(int lineNo, XUnaryOp op, Expression right) { + super(lineNo); + this.op = op; + this.right = right; + } + + @Override + public void accept(ASTVisitor av) { + av.visit(this); + } + + @Override + public void visitChildren(ASTVisitor av) { + right.accept(av); + } + } + + static class XBinary extends Expression { + XBinaryOp op; + Expression left, right; + + public XBinary(int lineNo, XBinaryOp op, Expression left, Expression right) { + super(lineNo); + this.op = op; + this.left = left; + this.right = right; + } + + @Override + public void accept(ASTVisitor av) { + av.visit(this); + } + + @Override + public void visitChildren(ASTVisitor av) { + left.accept(av); + right.accept(av); + } + } + + static class XReference extends Expression { + String name; + + public XReference(int lineNo, String name) { + super(lineNo); + this.name = name; + } + + @Override + public void accept(ASTVisitor av) { + av.visit(this); + } + } + + static class XCall extends Expression { + XReference ref; + List params; + + public XCall(int lineNo, XReference ref, List params) { + super(lineNo); + this.ref = ref; + this.params = params; + + System.out.printf("new call: %s ", ref.name); + params.forEach(p -> System.out.printf(" %s", p)); + System.out.println(); + } + + @Override + public void accept(ASTVisitor av) { + av.visit(this); + } + + @Override + public void visitChildren(ASTVisitor av) { + ref.accept(av); + accept(params, av); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("[call "); + sb.append(ref); + params.forEach(x -> sb.append(x.toString()).append(", ")); + sb.append("]"); + return sb.toString(); + } + } + + // return type? + static class XFunction extends Expression { + final List params; + final Statements statements; + + public XFunction(int lineNo, List params, Statements statements) { + super(lineNo); + this.params = params; + this.statements = statements; + } + + @Override + public void accept(ASTVisitor av) { + av.visit(this); + } + + @Override + public void visitChildren(ASTVisitor av) { + statements.accept(av); + } + } + + static class XInteger extends Expression { + long value; + + public XInteger(int lineNo, long value) { + super(lineNo); + this.value = value; + } + + @Override + public void accept(ASTVisitor av) { + av.visit(this); + } + } + + static class XReal extends Expression { + double value; + + public XReal(int lineNo, double value) { + super(lineNo); + this.value = value; + } + + @Override + public void accept(ASTVisitor av) { + av.visit(this); + } + } + + static class XString extends Expression { + String value; + + public XString(int lineNo, String value) { + super(lineNo); + this.value = value; + } + + @Override + public void accept(ASTVisitor av) { + av.visit(this); + } + } + + static class XBool extends Expression { + boolean value; + + public XBool(int lineNo, boolean value) { + super(lineNo); + this.value = value; + } + + @Override + public void accept(ASTVisitor av) { + av.visit(this); + } + } +} diff --git a/src/notzed.scripta/classes/au/notzed/scripta/ASTBuilder.java b/src/notzed.scripta/classes/au/notzed/scripta/ASTBuilder.java new file mode 100644 index 0000000..742f119 --- /dev/null +++ b/src/notzed.scripta/classes/au/notzed/scripta/ASTBuilder.java @@ -0,0 +1,244 @@ +/* + * Copyright (C) 2023 Michael Zucchi + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package au.notzed.scripta; + +import au.notzed.scripta.AST.*; +import static au.notzed.scripta.ScriptAParser.*; +import java.util.ArrayList; +import java.util.List; + +import org.antlr.v4.runtime.Token; + +public class ASTBuilder extends ScriptABaseVisitor { + + List errors = new ArrayList<>(); + + @Override + public AST.ScriptA visitScript(ScriptContext ctx) { + return new ScriptA(visitStatements(ctx.statements()).statements); + } + + @Override + public AST.Statements visitStatements(StatementsContext ctx) { + System.out.printf("statements %s\n", ctx); + return new AST.Statements(ctx.start.getLine(), ctx.statement().stream().map(this::visitStatement).toList()); + } + + public AST.Statement visitStatement(StatementContext ctx) { + System.out.println("visit statement " + ctx.getText()); + return (AST.Statement)visit(ctx); + } + + @Override + public AST.SIf visitIfStatement(IfStatementContext ctx) { + System.out.println("visit if statement " + ctx.getText()); + ValueExprContext valX = ctx.valueExpr(); + AST ast = ctx.valueExpr().accept(this); + if (ctx.rest == null) { + return new AST.SIf(ctx.start.getLine(), (Expression)ctx.valueExpr().accept(this), visitStatements(ctx.then)); + } else { + return new AST.SIf(ctx.start.getLine(), (Expression)ctx.valueExpr().accept(this), visitStatements(ctx.then), visitStatements(ctx.rest)); + } + } + + @Override + public AST.SWhile visitWhileStatement(WhileStatementContext ctx) { + System.out.println("visit while statement " + ctx.getText()); + return new SWhile(ctx.start.getLine(), (Expression)ctx.valueExpr().accept(this), visitStatements(ctx.when)); + } + + @Override + public AST visitDeclStatement(DeclStatementContext ctx) { + System.out.println("visit decl statement " + ctx.getText()); + return new SDeclare(ctx.start.getLine(), visitReference(ctx.reference())); + } + + @Override + public AST.SAssign visitAssignStatement(AssignStatementContext ctx) { + System.out.println("visit assign statement " + ctx.getText()); + return new AST.SAssign(ctx.start.getLine(), visitReference(ctx.reference()), visitValueExpr(ctx.valueExpr())); + } + + public AST.Expression visitValueExpr(ValueExprContext ctx) { + return (AST.Expression)ctx.accept(this); + } + + @Override + public AST visitCallStatement(CallStatementContext ctx) { + System.out.println("visit call statement " + ctx.getText()); + return new SCall(ctx.start.getLine(), visitCallExpr(ctx.callExpr())); + } + + @Override + public AST.XFunction visitFuncExpr(FuncExprContext ctx) { + System.out.println("visit func expr " + ctx.getText()); + return new XFunction( + ctx.start.getLine(), + ctx.ID().stream().map(a -> a.getText()).toList(), + ctx.statements() != null + ? visitStatements(ctx.statements()) + : AST.Statements.EMPTY + ); + } + + @Override + public AST.XCall visitCallExpr(CallExprContext ctx) { + return new XCall( + ctx.start.getLine(), + visitReference(ctx.reference()), + ctx.valueExpr().stream().map(v -> (AST.Expression)v.accept(this)).toList()); + } + + @Override + public AST visitBreakStatement(BreakStatementContext ctx) { + switch (ctx.start.getType()) { + case BREAK: + case CONTINUE: + case RETURN: + break; + default: + throw new UnsupportedOperationException(); + } + return super.visitBreakStatement(ctx); + } + + @Override + public AST.SReturn visitReturnStatement(ReturnStatementContext ctx) { + if (ctx.valueExpr() != null) { + return new AST.SReturn(ctx.start.getLine(), visitValueExpr(ctx.valueExpr())); + } else { + return new AST.SReturn(ctx.start.getLine()); + } + } + + /* ***************************************************************** */ + @Override + public AST.Expression visitValueGroupExpr(ValueGroupExprContext ctx) { + System.out.printf("visit group\n"); + return visitValueExpr(ctx.valueExpr()); + } + + XUnaryOp valueUnaryOp(Token op) { + switch (op.getType()) { + case ADD: + return XUnaryOp.NOP; + case SUB: + return XUnaryOp.NEG; + case NOT: + return XUnaryOp.NOT; + default: + throw new UnsupportedOperationException(op.getLine() + ": " + VOCABULARY.getDisplayName(op.getType())); + } + } + + @Override + public AST.XUnary visitValueUnaryExpr(ValueUnaryExprContext ctx) { + return new AST.XUnary( + ctx.start.getLine(), + valueUnaryOp(ctx.op), + (Expression)visit(ctx.rightValue)); + } + + XBinaryOp valueBinaryOp(Token op) { + switch (op.getType()) { + case ADD: + return XBinaryOp.ADD; + case SUB: + return XBinaryOp.SUB; + case MUL: + return XBinaryOp.MUL; + case DIV: + return XBinaryOp.DIV; + case MOD: + return XBinaryOp.MOD; + case AAND: + return XBinaryOp.AAND; + case OOR: + return XBinaryOp.OOR; + case XXOR: + return XBinaryOp.XXOR; + case LT: + return XBinaryOp.CLT; + case LE: + return XBinaryOp.CLE; + case GT: + return XBinaryOp.CGT; + case GE: + return XBinaryOp.CGE; + case EQ: + return XBinaryOp.CEQ; + case NE: + return XBinaryOp.CNE; + default: + throw new UnsupportedOperationException(op.getLine() + ": " + VOCABULARY.getDisplayName(op.getType())); + } + } + + @Override + public AST.XBinary visitValueBinaryExpr(ValueBinaryExprContext ctx) { + XBinary xb = new XBinary( + ctx.op.getLine(), + valueBinaryOp(ctx.op), + (Expression)visit(ctx.leftValue), + (Expression)visit(ctx.rightValue)); + System.out.printf("visit binary %s %s %s\n", xb.left, xb.op, xb.right); + return new XBinary( + ctx.op.getLine(), + valueBinaryOp(ctx.op), + (Expression)visit(ctx.leftValue), + (Expression)visit(ctx.rightValue)); + } + + Expression visitLiteral(Token lit) { + switch (lit.getType()) { + case INTEGER: { + try { + return new XInteger(lit.getLine(), Long.parseLong(lit.getText())); + } catch (NumberFormatException x) { + errors.add("Invalid INTEGER: " + lit.getText()); + return new XInteger(lit.getLine(), Long.MAX_VALUE); + } + } + case FLOAT: { + try { + return new XReal(lit.getLine(), Double.parseDouble(lit.getText())); + } catch (NumberFormatException x) { + errors.add("Invalid REAL: " + lit.getText()); + return new XReal(lit.getLine(), Double.NaN); + } + } + case STRING: + return new XString(lit.getLine(), lit.getText()); + case TRUE: + return new XBool(lit.getLine(), true); + case FALSE: + return new XBool(lit.getLine(), false); + default: + throw new UnsupportedOperationException(VOCABULARY.getDisplayName(lit.getType())); + } + } + + @Override + public AST visitLiteral(LiteralContext ctx) { + return visitLiteral(ctx.start); + } + + @Override + public AST.XReference visitReference(ReferenceContext ctx) { + return new XReference(ctx.start.getLine(), String.join(".", ctx.ID().stream().map(t -> t.getText()).toList())); + } +} diff --git a/src/notzed.scripta/classes/au/notzed/scripta/ASTPrinter.java b/src/notzed.scripta/classes/au/notzed/scripta/ASTPrinter.java new file mode 100644 index 0000000..e15e3a2 --- /dev/null +++ b/src/notzed.scripta/classes/au/notzed/scripta/ASTPrinter.java @@ -0,0 +1,183 @@ +/* + * Copyright (C) 2023 Michael Zucchi + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package au.notzed.scripta; + +import java.util.Iterator; + +public class ASTPrinter implements ASTVisitor { + StringBuilder d = new StringBuilder(); + + void down() { + d.append("\t"); + } + + void up() { + d.setLength(d.length() - 1); + } + + @Override + public void visit(AST.ScriptA a) { + ASTVisitor.super.visit(a); + } + + @Override + public void visit(AST.Statements s) { + s.statements.forEach(x -> x.accept(this)); + } + + @Override + public void visit(AST.SIf s) { + System.out.printf("%sif (", d); + s.test.accept(this); + System.out.println(")"); + down(); + s.then.accept(this); + up(); + s.rest.ifPresent(r -> { + System.out.printf("%selse", d); + down(); + r.accept(this); + up(); + }); + System.out.printf("%sfi\n", d); + } + + @Override + public void visit(AST.SWhile s) { + System.out.printf("%swhile (", d); + s.test.accept(this); + System.out.println(")"); + down(); + s.when.accept(this); + up(); + System.out.printf("%swend\n", d); + } + + @Override + public void visit(AST.SDeclare s) { + System.out.printf("var %s%s\n", d, s.ref.name); + } + + @Override + public void visit(AST.SAssign s) { + System.out.printf("%s%s = ", d, s.ref.name); + s.value.accept(this); + System.out.println(); + } + + @Override + public void visit(AST.SCall s) { + System.out.printf("%s", d); + s.call.accept(this); + System.out.println(); + } + + @Override + public void visit(AST.SBreak s) { + System.out.print(d); + System.out.print(s.op); + s.label.ifPresent(l -> System.out.print(" " + l)); + System.out.println(); + } + + @Override + public void visit(AST.SReturn s) { + System.out.print(d); + System.out.print("return"); + s.res.ifPresent(l -> { + System.out.print(" "); + l.accept(this); + }); + System.out.println(); + } + + /* *********************** */ + @Override + public void visit(AST.XUnary e) { + System.out.print(e.op); + System.out.print("( "); + e.right.accept(this); + System.out.print(" )"); + } + + @Override + public void visit(AST.XBinary e) { + System.out.print("( "); + e.left.accept(this); + System.out.print(" "); + System.out.print(e.op); + System.out.print(" "); + e.right.accept(this); + System.out.print(" )"); + } + + @Override + public void visit(AST.XCall e) { + e.ref.accept(this); + System.out.print("("); + Iterator it = e.params.iterator(); + if (it.hasNext()) + it.next().accept(this); + while (it.hasNext()) { + System.out.print(", "); + it.next().accept(this); + } + System.out.print(")"); + } + + @Override + public void visit(AST.XFunction e) { + System.out.print("function ("); + Iterator it = e.params.iterator(); + if (it.hasNext()) + System.out.print(it.next()); + while (it.hasNext()) { + System.out.print(", "); + System.out.print(it.next()); + } + System.out.print(") = {\n"); + down(); + visit(e.statements); + up(); + System.out.printf("%s}\n", d); + } + + @Override + public void visit(AST.XReference e) { + System.out.print(e.name); + } + + @Override + public void visit(AST.XBool e) { + System.out.printf("%s", e.value); + } + + @Override + public void visit(AST.XInteger e) { + System.out.printf("%dL", e.value); + } + + @Override + public void visit(AST.XReal e) { + System.out.printf("%fD", e.value); + } + + @Override + public void visit(AST.XString e) { + System.out.printf("`%s`", e.value); + } +} diff --git a/src/notzed.scripta/classes/au/notzed/scripta/ASTVisitor.java b/src/notzed.scripta/classes/au/notzed/scripta/ASTVisitor.java new file mode 100644 index 0000000..cd1548e --- /dev/null +++ b/src/notzed.scripta/classes/au/notzed/scripta/ASTVisitor.java @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2023 Michael Zucchi + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package au.notzed.scripta; + +import au.notzed.scripta.AST.*; +import java.util.List; + +public interface ASTVisitor { + + public default void visit(ScriptA a) { + for (Statement s: a.statements) + s.accept(this); + //a.statements.forEach(s -> s.accept(this)); + } + + public default void visit(Statements s) { + s.visitChildren(this); + } + + // statements + public default void visit(Statement s) { + s.visitChildren(this); + } + + public default void visit(SIf s) { + s.visitChildren(this); + } + + public default void visit(SWhile s) { + s.visitChildren(this); + } + + public default void visit(SDeclare s) { + s.visitChildren(this); + } + + public default void visit(SAssign s) { + s.visitChildren(this); + } + + public default void visit(SBreak s) { + s.visitChildren(this); + } + + public default void visit(SCall s) { + s.visitChildren(this); + } + + public default void visit(SReturn s) { + s.visitChildren(this); + } + + // expressions + public default void visit(Expression e) { + e.visitChildren(this); + } + + public default void visit(XUnary e) { + e.visitChildren(this); + } + + public default void visit(XBinary e) { + e.visitChildren(this); + } + + public default void visit(XReference e) { + e.visitChildren(this); + } + + public default void visit(XCall e) { + e.visitChildren(this); + } + + public default void visit(XFunction e) { + e.visitChildren(this); + } + + public default void visit(XBool e) { + e.visitChildren(this); + } + + public default void visit(XInteger e) { + e.visitChildren(this); + } + + public default void visit(XReal e) { + e.visitChildren(this); + } + + public default void visit(XString e) { + e.visitChildren(this); + } + +} diff --git a/src/notzed.scripta/classes/au/notzed/scripta/Compiler.java b/src/notzed.scripta/classes/au/notzed/scripta/Compiler.java new file mode 100644 index 0000000..539a0c3 --- /dev/null +++ b/src/notzed.scripta/classes/au/notzed/scripta/Compiler.java @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2023 Michael Zucchi + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package au.notzed.scripta; + +import static au.notzed.scripta.ScriptAParser.VOCABULARY; +import java.util.stream.Stream; +import org.antlr.v4.runtime.CharStream; +import org.antlr.v4.runtime.CharStreams; +import org.antlr.v4.runtime.CommonTokenStream; +import org.antlr.v4.runtime.ParserRuleContext; +import org.antlr.v4.runtime.Token; +import org.antlr.v4.runtime.tree.ParseTree; + +public class Compiler { + + static void dump(String s, ParseTree p) { + if (p.getPayload() instanceof ParserRuleContext t) { + System.out.printf("%s%s (%s)\n", s, t.start.getText(), t.getClass()); + } else if (p.getPayload() instanceof Token t) { + System.out.printf("%s%s\n", s, VOCABULARY.getDisplayName(t.getType())); + } else { + System.out.printf("%s%s\n", s, p.getPayload().getClass()); + } + for (int i = 0; i < p.getChildCount(); i++) { + dump(s + " ", p.getChild(i)); + } + } + + public static void main(String[] args) { + String src = """ + c = (2 + a) + a = 2 + b = 3 + c = (2 + a) + print(a + b, c, "hello", (3 + "foo")) + bob = function (a, b, c) { + return a + 2; + } + if (a == 2) { + return; + } + while (a < 1) { a = a + 0.1 } + """; + CharStream inputStream = CharStreams.fromString(src); + var lexer = new ScriptALexer(inputStream); + var tokenStream = new CommonTokenStream(lexer); + + int line[] = new int[1]; + Stream.of(src.split("\n")).map(l -> String.format("%5d: %s", ++line[0], l)).forEach(System.out::println); + + if (false) { + Token t; + while ((t = lexer.nextToken()).getType() != Token.EOF) { + System.out.println(t); + } + } + + var parser = new ScriptAParser(tokenStream); + var cst = parser.script(); + + dump(" ", cst); + + AST.ScriptA script = new ASTBuilder().visitScript(cst); + + System.out.printf("script(%d):\n", script.statements.size()); + script.statements.forEach(s -> System.out.printf(" %s\n", s)); + + new ASTPrinter().visit(script); + + if (false) { + System.out.println("visitor"); + new ASTVisitor() { + @Override + public void visit(AST.SCall s) { + System.out.printf(" call\n"); + ASTVisitor.super.visit(s); + } + + @Override + public void visit(AST.XBinary e) { + System.out.printf(" binary %s\n", e.op); + ASTVisitor.super.visit(e); + } + + @Override + public void visit(AST.XReference e) { + System.out.printf(" ref %s\n", e.name); + ASTVisitor.super.visit(e); + } + }.visit(script); + } + } + +} diff --git a/src/notzed.scripta/classes/au/notzed/scripta/Generator.java b/src/notzed.scripta/classes/au/notzed/scripta/Generator.java new file mode 100644 index 0000000..f3e1832 --- /dev/null +++ b/src/notzed.scripta/classes/au/notzed/scripta/Generator.java @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2023 Michael Zucchi + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package au.notzed.scripta; + +public class Generator { + +} diff --git a/src/notzed.scripta/classes/module-info.java b/src/notzed.scripta/classes/module-info.java new file mode 100644 index 0000000..ee3fd02 --- /dev/null +++ b/src/notzed.scripta/classes/module-info.java @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2023 Michael Zucchi + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +module notzed.scripta { + requires org.antlr.antlr4.runtime; + requires org.objectweb.asm; +} diff --git a/src/notzed.scripta/gen/ScriptA.g4 b/src/notzed.scripta/gen/ScriptA.g4 new file mode 100644 index 0000000..d991268 --- /dev/null +++ b/src/notzed.scripta/gen/ScriptA.g4 @@ -0,0 +1,96 @@ +// -*- Mode:text; tab-width:4; electric-indent-mode: nil; indent-line-function:insert-tab; -*- + +// A basic c-like language with optional ';' + +// if (test) { } [ else { } ] +// while (test) { } + +grammar ScriptA; + +script + : statements? EOF; + +statements + : statement (';'? statement)* ';'?; + +statement + : (label=ID ':')? IF '(' valueExpr ')' '{' then=statements? '}' ( ELSE '{' rest=statements? '}' )? # ifStatement +// | (label=ID ':')? SWITCH '(' valueExpr ')' '{' cases* '}' # switchStatement + | (label=ID ':')? WHILE '(' valueExpr ')' '{' when=statements? '}' # whileStatement + | scope? reference # declStatement + | scope? reference '=' valueExpr # assignStatement + | callExpr # callStatement + | CONTINUE (label=ID) ? # breakStatement + | BREAK (label=ID) ? # breakStatement + | RETURN valueExpr ? # returnStatement + ; + + +valueExpr + : '(' valueExpr ')' # valueGroupExpr + | op=('!'|'-'|'+') rightValue=valueExpr # valueUnaryExpr + | leftValue=valueExpr op=('*'|'/'|'%') rightValue=valueExpr # valueBinaryExpr + | leftValue=valueExpr op=('&'|'|'|'+'|'-') rightValue=valueExpr # valueBinaryExpr + | leftValue=valueExpr op=('&&'|'||'|'^^') rightValue=valueExpr # valueBinaryExpr + | leftValue=valueExpr op=(LT|LE|GT|GE|EQ|NE) rightValue=valueExpr # valueBinaryExpr + | lit=literal # valueLiteralExpr + | ref=reference # valueReferenceExpr + | call=callExpr # valueCallExpr + | func=funcExpr # valueFunctionExpr + ; + +callExpr : reference '(' (valueExpr (',' valueExpr)*)? ')'; +funcExpr : FUNC '(' (ID (',' ID) *) ? ')' '{' statements? '}'; + +IF : 'if'; +ELSE : 'else'; +SWITCH : 'switch'; +CASE : 'case'; +WHILE : 'while'; +CONTINUE : 'continue'; +BREAK : 'break'; +RETURN : 'return'; +FUNC : 'function'; +DEFAULT : 'default'; + +GLOBAL : 'global'; +LOCAL : 'local'; +PLAYER : 'player'; +CONST : 'const'; + +literal : INTEGER | FLOAT | STRING | TRUE | FALSE; +scope : GLOBAL | LOCAL | PLAYER | CONST; +reference : ID ('.' ID)*; + +TRUE : 'true'; +FALSE : 'false'; + +LT : '<'; +LE : '<='; +GT : '>'; +GE : '>='; +EQ : '=='; +NE : '!='; + +CMP : ( LT | LE | GT | GE | EQ | NE ); + +ADD : '+'; +SUB : '-'; +MUL : '*'; +DIV : '/'; +MOD : '%'; +NOT : '!'; + +AAND : '&&'; +OOR : '||'; +XXOR : '^^'; + +INTEGER : [0-9]+; +FLOAT : [0-9]+ '.' ([0-9]+)? ([eE] [+-]? [0-9]+)?; +STRING : '"' (~[\\"] | '\\' [\\"])* '"' + | '\'' (~[\\'] | '\\' [\\'])* '\''; +ID : [a-zA-Z_][0-9a-zA-Z_]*; + +NL : ( '\n' | '\r\n' | '\r' ) -> channel(HIDDEN); +COMMENT : '#' ~[\r\n]* -> channel(HIDDEN); +WS : [ \t] -> channel(HIDDEN); diff --git a/src/notzed.scripta/gen/gen.make b/src/notzed.scripta/gen/gen.make new file mode 100644 index 0000000..65969b7 --- /dev/null +++ b/src/notzed.scripta/gen/gen.make @@ -0,0 +1,5 @@ + +notzed.scripta_ANTLR4 = ScriptA +notzed.scripta-ScriptA_ANTLR4PACKAGE = au.notzed.scripta +notzed.scripta-ScriptA_ANTLR4FLAGS = -visitor -no-listener + -- 2.39.2