Permalink
Browse files

Dev drop

  • Loading branch information...
LadyCailin committed Dec 18, 2018
1 parent 4c327a2 commit f365b185a76da4e8a411f0e032ef1ed57b153055
@@ -78,19 +78,19 @@
/**
* The name of the preference
*/
public String name;
public final String name;
/**
* The value of the preference, as a string
*/
public String value;
public final String value;
/**
* The allowed type of this value
*/
public Type allowed;
public final Type allowed;
/**
* The description of this preference. Used to write out to file.
*/
public String description;
public final String description;

/**
* The object representation of this value. Should not be used directly.
@@ -374,7 +374,7 @@ private void save() {
}

/**
* Sets the comment line length.
* Sets the comment line length. Defaults to 120.
*
* @param lineLength The length, an integer greater than 0.
* @throws IllegalArgumentException If {@code lineLength} is less than 1.
@@ -8,7 +8,6 @@
import com.laytonsmith.PureUtilities.Common.ArrayUtils;
import com.laytonsmith.PureUtilities.Common.FileUtil;
import com.laytonsmith.PureUtilities.Common.Misc;
import com.laytonsmith.PureUtilities.Common.OSUtils;
import com.laytonsmith.PureUtilities.Common.RSAEncrypt;
import com.laytonsmith.PureUtilities.Common.StreamUtils;
import com.laytonsmith.PureUtilities.Common.StringUtils;
@@ -21,7 +20,7 @@
import com.laytonsmith.abstraction.StaticLayer;
import com.laytonsmith.annotations.api;
import com.laytonsmith.core.compiler.OptimizationUtilities;
import com.laytonsmith.core.constructs.CString;
import com.laytonsmith.core.precompiler.Precompiler;
import com.laytonsmith.core.constructs.Target;
import com.laytonsmith.core.exceptions.ConfigCompileException;
import com.laytonsmith.core.exceptions.ConfigCompileGroupException;
@@ -31,7 +30,6 @@
import com.laytonsmith.core.functions.Function;
import com.laytonsmith.core.functions.FunctionBase;
import com.laytonsmith.core.functions.FunctionList;
import com.laytonsmith.core.functions.Scheduling;
import com.laytonsmith.persistence.PersistenceNetwork;
import com.laytonsmith.persistence.io.ConnectionMixinFactory;
import com.laytonsmith.tools.ExampleLocalPackageInstaller;
@@ -101,6 +99,9 @@
private static final ArgumentParser UI_MODE;
private static final ArgumentParser NEW_MODE;
private static final ArgumentParser SITE_DEPLOY;
private static final ArgumentParser NEW_PROJECT_MODE;
private static final ArgumentParser COMPILE_MODE;
private static final ArgumentParser EXECUTE_MODE;

static {
MethodScriptFileLocations.setDefault(new MethodScriptFileLocations());
@@ -261,6 +262,21 @@
.addFlag('f', "force", "Forces the file to be overwritten, even if it already exists");
suite.addMode("new", NEW_MODE);

NEW_PROJECT_MODE = ArgumentParser.GetParser()
.addDescription("Creates the base files necessary for a new compilable project.")
.addArgument("The project location. If the directory does not exist, it is created.", "<directory>",
true);
suite.addMode("new-project", NEW_PROJECT_MODE);
COMPILE_MODE = ArgumentParser.GetParser()
.addDescription("")
.addArgument("config", "Default to build.ini, but can be changed here. If the specified config file is"
+ " not present, it is not created. To create a template, use the new-project tool.", false);
suite.addMode("compile", COMPILE_MODE);
EXECUTE_MODE = ArgumentParser.GetParser()
.addDescription("Executes a precompiled .msc file")
.addArgument("The file to execute", "<file>", true);
suite.addMode("execute", EXECUTE_MODE);

ARGUMENT_SUITE = suite;
}

@@ -711,25 +727,18 @@ public static void main(String[] args) throws Exception {
File config = new File(configString);
SiteDeploy.run(generatePrefs, useLocalCache, config, "", doValidation, !noProgressClear);
} else if(mode == NEW_MODE) {
String li = OSUtils.GetLineEnding();
for(String file : parsedArgs.getStringListArgument()) {
File f = new File(file);
if(f.exists() && !parsedArgs.isFlagSet('f')) {
System.out.println(file + " already exists, refusing to create");
continue;
}
f.createNewFile();
f.setExecutable(true);
FileUtil.write("#!/usr/bin/env /usr/local/bin/mscript"
+ li
+ "<!" + li
+ "\tstrict;" + li
+ "\tname: " + f.getName() + ";" + li
+ "\tauthor: " + StaticLayer.GetConvertor().GetUser(null) + ";" + li
+ "\tcreated: " + new Scheduling.simple_date().exec(Target.UNKNOWN, null, new CString("yyyy-MM-dd", Target.UNKNOWN)).val() + ";" + li
+ "\tdescription: " + ";" + li
+ ">" + li + li, f, true);
Precompiler.initializeFile(f, parsedArgs.isFlagSet('f'));
}
} else if(mode == NEW_PROJECT_MODE) {
String file = parsedArgs.getStringArgument();
Precompiler.initialize(new File(file));
System.exit(0);
} else if(mode == COMPILE_MODE) {
String config = parsedArgs.getStringArgument();
File f = new File(config);
Precompiler.compile(f.getParentFile(), f.getName());
} else {
throw new Error("Should not have gotten here");
}
@@ -1277,7 +1277,7 @@ public static File GetFileFromArgument(String arg, Environment env, Target t, Fi
}
//Ok, it's not absolute, so we need to see if we're in cmdline mode or not.
//If so, we use the root directory, not the target.
if(env != null && InCmdLine(env)) {
if(env != null && InCmdLine(env) && !InCompiler(env)) {
return new File(env.getEnv(GlobalEnv.class).GetRootFolder(), arg);
} else if(t.file() == null) {
throw new CREIOException("Unable to receive a non-absolute file with an unknown target", t);
@@ -1297,6 +1297,17 @@ public static boolean InCmdLine(Environment environment) {
&& (Boolean) environment.getEnv(GlobalEnv.class).GetCustom("cmdline");
}

/**
* Returns true if currently running in the compiler mode. Compiler mode is when the interpreter was
* launched with the file name, rather than in REPL mode.
* @param environment
* @return
*/
public static boolean InCompiler(Environment environment) {
return environment.getEnv(GlobalEnv.class).GetCustom("compiler") instanceof Boolean
&& (Boolean) environment.getEnv(GlobalEnv.class).GetCustom("compiler");
}

/**
* This verifies that the type required is actually present, and returns the value, cast to the appropriate type,
* or, if not the correct type, a CRE.
@@ -0,0 +1,159 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package com.laytonsmith.core.precompiler;

import com.laytonsmith.PureUtilities.Common.FileUtil;
import com.laytonsmith.PureUtilities.Common.OSUtils;
import com.laytonsmith.PureUtilities.Preferences;
import com.laytonsmith.abstraction.StaticLayer;
import com.laytonsmith.core.MethodScriptCompiler;
import com.laytonsmith.core.ParseTree;
import com.laytonsmith.core.constructs.CString;
import com.laytonsmith.core.constructs.Target;
import com.laytonsmith.core.exceptions.ConfigCompileException;
import com.laytonsmith.core.exceptions.ConfigCompileGroupException;
import com.laytonsmith.core.functions.Scheduling;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.apache.commons.io.FileUtils;

/**
*
* @author caismith
*/
public class Precompiler {

//***************************************************************************************
// View Code
//***************************************************************************************

private static final Preferences.Preference MAIN = new Preferences.Preference("main", "main.ms",
Preferences.Type.FILE, "The name of the main file. This is the entry point into the program.");
private static final Preferences.Preference LIBS = new Preferences.Preference("libs", "", Preferences.Type.STRING,
"Other projects may be included, either msc executables or other project directories. This should be a"
+ " comma separated list of file paths.");
private static final Preferences.Preference OUTPUT = new Preferences.Preference("output", "", Preferences.Type.FILE,
"The output executable file. The file name MUST end in .msc.");

/**
* Returns the
* @return
*/
private static Preferences getDefaultPrefs() {
List<Preferences.Preference> prefs = new ArrayList<>();
prefs.add(MAIN);
prefs.add(LIBS);
prefs.add(OUTPUT);
return new Preferences("MethodScript Compiler", Logger.global, prefs, "This provides the"
+ " compilation parameters for the project. See each configuration setting for more details.");
}

/**
* Given a project directory and config file name, builds the project.
* @param projectDirectory
* @param configFile
* @throws IOException
* @throws com.laytonsmith.core.exceptions.ConfigCompileException
* @throws com.laytonsmith.core.exceptions.ConfigCompileGroupException
*/
public static void compile(File projectDirectory, String configFile) throws IOException, ConfigCompileException,
ConfigCompileGroupException {
if(!new File(projectDirectory, configFile).exists()) {
System.out.println("Could not find config file, cannot continue.");
System.exit(1);
}
Preferences pref = getDefaultPrefs();
pref.init(new File(projectDirectory, configFile));
File main = pref.getFilePreference(MAIN.name);
String libsS = pref.getStringPreference(LIBS.name);
List<File> libs = Stream.of(libsS.split(",")).map(s -> new File(s)).collect(Collectors.toList());
File output = pref.getFilePreference(OUTPUT.name);
if(!output.getName().endsWith(".msc")) {
System.out.println("The output file name must end in .msc");
System.exit(1);
}
new Precompiler(projectDirectory, main, libs, output).compile();
}

/**
* Initializes the project directory, creating the base files necessary. Nothing that already exists
* will be overwritten.
* @param directory
* @throws IOException
*/
public static void initialize(File directory) throws IOException {
directory.mkdirs();
Preferences pref = getDefaultPrefs();
File config = new File(directory, "build.ini");
if(config.exists()) {
System.out.println("Build file already exists, refusing to continue");
System.exit(1);
}
pref.init(config);
for(String f : new String[]{"main.ms", "auto_include.ms"}) {
try {
initializeFile(new File(directory, f), false);
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
}

public static void initializeFile(File f, boolean force) throws IOException {
if(f.exists() && !force) {
System.out.println(f + " already exists, refusing to create");
throw new IOException();
}
f.createNewFile();
f.setExecutable(true);
String li = OSUtils.GetLineEnding();
FileUtil.write("#!/usr/bin/env /usr/local/bin/mscript"
+ li
+ "<!" + li
+ "\tstrict;" + li
+ "\tname: " + f.getName() + ";" + li
+ "\tauthor: " + StaticLayer.GetConvertor().GetUser(null) + ";" + li
+ "\tcreated: " + new Scheduling.simple_date().exec(Target.UNKNOWN, null, new CString("yyyy-MM-dd", Target.UNKNOWN)).val() + ";" + li
+ "\tdescription: " + ";" + li
+ ">" + li + li, f, true);
}

//****************************************************************************************
// End View Code
//****************************************************************************************

private final File project;
private final File main;
private final List<File> libs;
private final File output;

public Precompiler(File project, File main, List<File> libs, File output) {
this.project = project;
this.main = main;
this.libs = libs;
this.output = output;
}

public void compile() throws IOException, ConfigCompileException, ConfigCompileGroupException {
Map<File, ParseTree> includeMap = new HashMap<>();
compile(main, includeMap);
}

private ParseTree compile(File file, Map<File, ParseTree> includes) throws IOException, ConfigCompileException, ConfigCompileGroupException {
if(!includes.containsKey(file)) {
MethodScriptCompiler.compile(MethodScriptCompiler.lex(FileUtils.readFileToString(file), file, true));

}
return includes.get(file);
}
}
Oops, something went wrong.

0 comments on commit f365b18

Please sign in to comment.