diff --git a/osrc/SATSolver/Ostrava.cyp b/osrc/SATSolver/Ostrava.cyp index c5ec9e1..bda18f2 100644 --- a/osrc/SATSolver/Ostrava.cyp +++ b/osrc/SATSolver/Ostrava.cyp @@ -6,12 +6,16 @@ banik pyco tryda Ostrava { - rynek(){ + rynek(chachar[] vstup){ + kaj (vstup == chuj){ + Konzola.pravit("Chybi vstupni soubor") pyco + davaj pyco + } + toz Parsovac p = zrob Parsovac() pyco - toz CNF cnf = p.vyparsuj("resources/sats/06.txt") pyco + toz CNF cnf = p.vyparsuj(zrob Dryst(vstup)) pyco Konzola.pravit("Vyparsovano") pyco Konzola.pravit("Zacinam resit") pyco - dechrobok pyco toz Resic r = zrob Resic(cnf) pyco r.rubej() pyco diff --git a/src/cz/cvut/fit/ostrajava/Compile.java b/src/cz/cvut/fit/ostrajava/Compile.java new file mode 100644 index 0000000..d4a1ff4 --- /dev/null +++ b/src/cz/cvut/fit/ostrajava/Compile.java @@ -0,0 +1,171 @@ +package cz.cvut.fit.ostrajava; + +/** + * Created by tomaskohout on 12/13/15. + */ + +import cz.cvut.fit.ostrajava.Compiler.*; +import cz.cvut.fit.ostrajava.Interpreter.ClassPool; +import cz.cvut.fit.ostrajava.Interpreter.Memory.Array; +import cz.cvut.fit.ostrajava.Parser.ASTCompilationUnit; +import cz.cvut.fit.ostrajava.Parser.Node; +import cz.cvut.fit.ostrajava.Parser.OSTRAJavaParser; +import cz.cvut.fit.ostrajava.Parser.ParseException; + +import java.io.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import cz.cvut.fit.ostrajava.Compiler.Class; + +public class Compile { + + final static String CLASS_TYPE_EXTENSION = "tryda"; + + public static void printHelp(){ + System.out.println("Pouziti: ostrajavac \n"+ + "kaj moznosti muzu byt: \n" + + "-d slozka pro vygenerovane .tryda soubory \n"); + } + + public static void exec(String[] args) throws Exception + { + if (args.length == 0) { + printHelp(); + System.exit(0); + } + + List filenames = new ArrayList<>(Arrays.asList(args)); + String outputDirectory = "."; + + for (int i = 0; i < args.length-1; i ++) { + String param = args[i]; + String value = args[i+1]; + + if (param.equals("-d")){ + filenames.remove(i); + filenames.remove(i); + outputDirectory = value; + } + } + + if (filenames.size() == 0){ + printHelp(); + System.exit(0); + } + + + List rootNodeList = parse(filenames); + + List classList = new ArrayList<>(); + OSTRAJavaCompiler compiler = new OSTRAJavaCompiler(); + + //First stage - precompilation + for (Node node: rootNodeList){ + classList.addAll(compiler.precompile(node)); + } + + //Second stage - compilation + ClassPool classPool = new ClassPool(classList); + + classList.clear(); + + for (Node node: rootNodeList){ + classList.addAll(compiler.compile(node, classPool)); + } + + removeClassfiles(outputDirectory); + + //Generate files + for (Class clazz: classList){ + Classfile.toFile(clazz, outputDirectory + clazz.getClassName() + "." + CLASS_TYPE_EXTENSION); + } + + + } + + protected static void removeClassfiles(String dir){ + File file = new File(dir); + if (!file.isDirectory()){ + System.out.println(dir + " is not a directory"); + System.exit(0); + } + + for (File dirFile: file.listFiles()){ + String extension = ""; + + int i = dirFile.getName().lastIndexOf('.'); + if (i > 0) { + extension = dirFile.getName().substring(i + 1); + } + + if (extension.equals(Compile.CLASS_TYPE_EXTENSION)) { + dirFile.delete(); + } + + } + + + } + + protected static List listAllFiles(List filenames){ + List files = new ArrayList<>(); + + for (String fileName: filenames) { + File file = new File(fileName); + files.addAll(getFilesRecursively(file)); + } + + return files; + } + + protected static List getFilesRecursively(File file){ + List files = new ArrayList<>(); + + if (file.isDirectory()){ + File[] dirFiles = file.listFiles(); + for (File dirFile: dirFiles){ + files.addAll(getFilesRecursively(dirFile)); + } + + }else{ + files.add(file); + } + + return files; + } + + protected static List parse(List filenames) throws FileNotFoundException, ParseException { + Reader fr = null; + OSTRAJavaParser jp = null; + + List rootNodeList = new ArrayList<>(); + + for (File file: listAllFiles(filenames)) { + + fr = new InputStreamReader(new FileInputStream(file)); + + if (jp == null){ + jp = new OSTRAJavaParser(fr); + }else{ + jp.ReInit(fr); + } + + try { + //Parse + jp.CompilationUnit(); + ASTCompilationUnit node = (ASTCompilationUnit) jp.rootNode(); + + rootNodeList.add(node); + } catch (ParseException e) { + System.out.println("Parsing exception in file " + file.getName()); + throw e; + } + } + + return rootNodeList; + } + + +} diff --git a/src/cz/cvut/fit/ostrajava/Compiler/ByteCode.java b/src/cz/cvut/fit/ostrajava/Compiler/ByteCode.java index b123280..3af74ff 100644 --- a/src/cz/cvut/fit/ostrajava/Compiler/ByteCode.java +++ b/src/cz/cvut/fit/ostrajava/Compiler/ByteCode.java @@ -41,7 +41,7 @@ public String toString() { int in = 0; for (Instruction i: instructions){ - sb.append(in + ": " + i + "\n"); + sb.append(i + System.getProperty("line.separator")); in++; } diff --git a/src/cz/cvut/fit/ostrajava/Compiler/Class.java b/src/cz/cvut/fit/ostrajava/Compiler/Class.java index c4b3a43..e8c9474 100644 --- a/src/cz/cvut/fit/ostrajava/Compiler/Class.java +++ b/src/cz/cvut/fit/ostrajava/Compiler/Class.java @@ -19,8 +19,6 @@ */ public class Class { - final String MAGIC_HEADER = "BANIK"; - protected List flags; protected String className; @@ -84,7 +82,7 @@ public void setFields(List fields) { this.fields = fields; } - public void addFields(Field field) { + public void addField(Field field) { this.fields.add(field); } @@ -217,18 +215,6 @@ public String toString() { sb.append(className + ">" + superName); return sb.toString(); -/* - sb.append(MAGIC_HEADER + "\n"); - - for (String flag : flags){ - sb.append(flag + "|"); - } - sb.append("\n"); - - sb.append(className + ">" + superName); - sb.append("\n"); - - return sb.toString();*/ } } diff --git a/src/cz/cvut/fit/ostrajava/Compiler/Classfile.java b/src/cz/cvut/fit/ostrajava/Compiler/Classfile.java new file mode 100644 index 0000000..12f5a5f --- /dev/null +++ b/src/cz/cvut/fit/ostrajava/Compiler/Classfile.java @@ -0,0 +1,186 @@ +package cz.cvut.fit.ostrajava.Compiler; + +import java.io.*; + +/** + * Created by tomaskohout on 12/13/15. + */ +public class Classfile { + + private static final int CONSTANTS_LINE = 1; + private static final int CLASS_LINE = 1; + private static final int SUPERCLASS_LINE = 1; + private static final int FIELDS_LINE = 1; + private static final int METHODS_LINE = 1; + private static final int LOCALS_LINE = 1; + private static final int INSTRUCTIONS_LINE = 1; + private static final int METHOD_NATIVE_LINE = 1; + + public static File toFile(Class clazz, String fileName) throws IOException { + File file = new File(fileName); + FileWriter fw = new FileWriter(file.getAbsoluteFile()); + BufferedWriter bw = new BufferedWriter(fw); + + bw.write(0xCA); + bw.write(0xFE); + bw.write(0xBA); + bw.write(0xBA); + bw.newLine(); + + + bw.write(clazz.constantPool.getSize() + ""); + bw.newLine(); + + for (String constant: clazz.constantPool.constants){ + bw.write(constant); + bw.newLine(); + } + + bw.write(clazz.getClassName()); + bw.newLine(); + bw.write(clazz.getSuperName() == null ? "" : clazz.getSuperName()); + bw.newLine(); + + bw.write(clazz.getFields().size()+""); + bw.newLine(); + + + for (Field field: clazz.getFields()){ + bw.write(field.toString()); + bw.newLine(); + } + + + bw.write(clazz.getMethods().size()+""); + bw.newLine(); + + for (Method method: clazz.getMethods()){ + bw.write(method.getDescriptor()); + bw.newLine(); + bw.write(method.getLocalVariablesCount() + ""); + bw.newLine(); + bw.write((method.isNativeMethod() ? 1 : 0) + ""); + bw.newLine(); + bw.write(method.getByteCode().getInstructions().size() + ""); + bw.newLine(); + bw.write(method.getByteCode().toString()); + } + + bw.close(); + return file; + } + + + public static Class fromFile(File file) throws IOException { + ConstantPool constantPool = new ConstantPool(); + Class clazz = new Class(); + clazz.constantPool = constantPool; + + BufferedReader br = new BufferedReader(new FileReader(file)); + + String line; + + int line_counter = 0; + int constants_size = -1; + int fields_size = -1; + int methods_size = -1; + int instructions_size = -1; + int method_start = 0; + int method_count = 0; + + Method method = null; + ByteCode byteCode = null; + + //I admit this is not my best code ever + while ((line = br.readLine()) != null) { + + if (line_counter == 0){ + if (line.equals(String.format("%d%d%d%d", 0xCA, 0XFE, 0xBA, 0xBA))){ + throw new IllegalArgumentException("File is not a OSTRAJava classfile"); + } + }else{ + if (line_counter == CONSTANTS_LINE){ + constants_size = Integer.parseInt(line); + }else{ + int constants_end = CONSTANTS_LINE + constants_size; + if (line_counter > CONSTANTS_LINE && line_counter <= CONSTANTS_LINE + constants_size){ + constantPool.addConstant(line); + }else{ + if (line_counter == constants_end + CLASS_LINE){ + clazz.setClassName(line); + }else{ + int classnames_end = constants_end + CLASS_LINE + SUPERCLASS_LINE; + + if (line_counter == classnames_end){ + clazz.setSuperName(line); + }else{ + if (line_counter == classnames_end + FIELDS_LINE){ + fields_size = Integer.parseInt(line); + }else{ + int fields_end = classnames_end + FIELDS_LINE + fields_size; + + if (line_counter > classnames_end + FIELDS_LINE && line_counter <= fields_end){ + Field field = new Field(line); + clazz.addField(field); + }else { + if (line_counter == fields_end + METHODS_LINE){ + methods_size = Integer.parseInt(line); + method_start = fields_end + METHODS_LINE + 1; + }else{ + if (line_counter == method_start){ + method = new Method(line); + clazz.addMethod(method); + method_count++; + }else { + if (line_counter == method_start + LOCALS_LINE) { + method.setLocalVariablesCount(Integer.parseInt(line)); + }else{ + if (line_counter == method_start + LOCALS_LINE + METHOD_NATIVE_LINE) { + int isNative = Integer.parseInt(line); + if (isNative == 1) { + method.addFlag(Method.MethodFlag.Native); + } + }else { + if (line_counter == method_start + LOCALS_LINE + METHOD_NATIVE_LINE + INSTRUCTIONS_LINE) { + instructions_size = Integer.parseInt(line); + byteCode = new ByteCode(); + method.setByteCode(byteCode); + } else { + if (line_counter > method_start + LOCALS_LINE+ METHOD_NATIVE_LINE + INSTRUCTIONS_LINE && line_counter <= method_start + LOCALS_LINE + METHOD_NATIVE_LINE + INSTRUCTIONS_LINE + instructions_size) { + byteCode.addInstruction(new Instruction(line)); + } else { + if (method_count >= methods_size) { + throw new IllegalArgumentException("End expected in the classfile provided"); + } else { + method = new Method(line); + clazz.addMethod(method); + method_start = method_start + LOCALS_LINE + METHOD_NATIVE_LINE + INSTRUCTIONS_LINE + instructions_size + 1; + } + } + } + } + } + } + } + } + } + } + } + } + } + } + + + line_counter++; + } + + + + br.close(); + + + + return clazz; + + } +} diff --git a/src/cz/cvut/fit/ostrajava/Compiler/ConstantPool.java b/src/cz/cvut/fit/ostrajava/Compiler/ConstantPool.java index 20056dc..97ecf5c 100644 --- a/src/cz/cvut/fit/ostrajava/Compiler/ConstantPool.java +++ b/src/cz/cvut/fit/ostrajava/Compiler/ConstantPool.java @@ -60,7 +60,9 @@ public ConstantPool(ClassPool classPool) { } - + public int getSize(){ + return constants.size(); + } public int addConstant(String constant){ diff --git a/src/cz/cvut/fit/ostrajava/Compiler/Field.java b/src/cz/cvut/fit/ostrajava/Compiler/Field.java index 3a95b42..0218c43 100644 --- a/src/cz/cvut/fit/ostrajava/Compiler/Field.java +++ b/src/cz/cvut/fit/ostrajava/Compiler/Field.java @@ -1,6 +1,7 @@ package cz.cvut.fit.ostrajava.Compiler; import cz.cvut.fit.ostrajava.Type.Type; +import cz.cvut.fit.ostrajava.Type.Types; import java.util.List; @@ -17,6 +18,12 @@ public Field(String name, Type type){ this.type = type; } + public Field(String descriptor){ + String[] parts = descriptor.split(":"); + this.name = parts[0]; + this.type = Types.fromString(parts[1]); + } + public String getName() { return name; } @@ -40,4 +47,9 @@ public List getFlags() { public void setFlags(List flags) { this.flags = flags; } + + @Override + public String toString() { + return getName() + ":" + getType(); + } } diff --git a/src/cz/cvut/fit/ostrajava/Compiler/Instruction.java b/src/cz/cvut/fit/ostrajava/Compiler/Instruction.java index fa06fa0..0536991 100644 --- a/src/cz/cvut/fit/ostrajava/Compiler/Instruction.java +++ b/src/cz/cvut/fit/ostrajava/Compiler/Instruction.java @@ -33,6 +33,16 @@ public Instruction(InstructionSet instruction, List operands){ this.operands = operands; } + public Instruction(String instructionString) { + String[] parts = instructionString.split(" "); + this.instruction = InstructionSet.fromString(parts[0]); + this.operands = new ArrayList(); + + for (int i=1; i getOperands() { return operands; } diff --git a/src/cz/cvut/fit/ostrajava/Compiler/InstructionSet.java b/src/cz/cvut/fit/ostrajava/Compiler/InstructionSet.java index fc711ac..d271e1f 100644 --- a/src/cz/cvut/fit/ostrajava/Compiler/InstructionSet.java +++ b/src/cz/cvut/fit/ostrajava/Compiler/InstructionSet.java @@ -76,4 +76,15 @@ public enum InstructionSet { public String toString() { return abbr; } + + public static InstructionSet fromString(String text) { + if (text != null) { + for (InstructionSet b : InstructionSet.values()) { + if (text.equalsIgnoreCase(b.abbr)) { + return b; + } + } + } + return null; + } } diff --git a/src/cz/cvut/fit/ostrajava/Compiler/Method.java b/src/cz/cvut/fit/ostrajava/Compiler/Method.java index e482843..bf1e6b0 100644 --- a/src/cz/cvut/fit/ostrajava/Compiler/Method.java +++ b/src/cz/cvut/fit/ostrajava/Compiler/Method.java @@ -47,6 +47,7 @@ public Method(String name, List args, String className, Type returnType) { } public Method(String descriptor) { + this.flags = new HashSet<>(); int classIndex = descriptor.indexOf("."); String methodPart = descriptor; diff --git a/src/cz/cvut/fit/ostrajava/Compiler/OSTRAJavaCompiler.java b/src/cz/cvut/fit/ostrajava/Compiler/OSTRAJavaCompiler.java index 85dafb8..8a0a630 100644 --- a/src/cz/cvut/fit/ostrajava/Compiler/OSTRAJavaCompiler.java +++ b/src/cz/cvut/fit/ostrajava/Compiler/OSTRAJavaCompiler.java @@ -374,7 +374,7 @@ protected List statement(ASTStatement node, int cycleStart, MethodC }else if (child instanceof ASTContinueStatement) { continueStatement(cycleStart, compilation); }else if (child instanceof ASTReturnStatement) { - returnStatement(child, compilation); + returnStatement(child.jjtGetNumChildren() > 0 ? child.jjtGetChild(0) : null, compilation); }else if (child instanceof ASTDebugStatement) { debugStatement(compilation); }else{ diff --git a/src/cz/cvut/fit/ostrajava/Interpreter/ClassPool.java b/src/cz/cvut/fit/ostrajava/Interpreter/ClassPool.java index 9ccbd7b..cf8efa0 100644 --- a/src/cz/cvut/fit/ostrajava/Interpreter/ClassPool.java +++ b/src/cz/cvut/fit/ostrajava/Interpreter/ClassPool.java @@ -22,7 +22,7 @@ public ClassPool(List classes) throws LookupException { //Find super class for (InterpretedClass ic: this.classes){ - if (ic.getSuperName() != null) { + if (ic.getSuperName() != null && ic.getSuperName().length() > 0) { ic.setSuperClass(lookupClass(ic.getSuperName())); } } diff --git a/src/cz/cvut/fit/ostrajava/Interpreter/Converter.java b/src/cz/cvut/fit/ostrajava/Interpreter/Converter.java index 4dbbeea..9c84073 100644 --- a/src/cz/cvut/fit/ostrajava/Interpreter/Converter.java +++ b/src/cz/cvut/fit/ostrajava/Interpreter/Converter.java @@ -57,6 +57,15 @@ public static char[] arrayToCharArray(Array array){ return chars; } + public static Array charArrayToArray(char[] charArray){ + Array array = new Array(charArray.length); + for (int i = 0; i < charArray.length; i++){ + StackValue charValue = new StackValue(charArray[i], StackValue.Type.Primitive); + array.set(i, charValue); + } + return array; + } + public static boolean[] byteArrayToBoolArray(byte[] bytes){ int[] intArray = byteArrayToIntArray(bytes); boolean[] res = new boolean[intArray.length]; diff --git a/src/cz/cvut/fit/ostrajava/Interpreter/InterpretedClass.java b/src/cz/cvut/fit/ostrajava/Interpreter/InterpretedClass.java index 496222e..5906ea1 100644 --- a/src/cz/cvut/fit/ostrajava/Interpreter/InterpretedClass.java +++ b/src/cz/cvut/fit/ostrajava/Interpreter/InterpretedClass.java @@ -21,7 +21,7 @@ public InterpretedClass(Class c) { //Copy for (Field field: c.getFields()){ - this.addFields(field); + this.addField(field); } for (Method method: c.getMethods()){ diff --git a/src/cz/cvut/fit/ostrajava/Interpreter/OSTRAJavaInterpreter.java b/src/cz/cvut/fit/ostrajava/Interpreter/OSTRAJavaInterpreter.java index a16d321..443d89d 100644 --- a/src/cz/cvut/fit/ostrajava/Interpreter/OSTRAJavaInterpreter.java +++ b/src/cz/cvut/fit/ostrajava/Interpreter/OSTRAJavaInterpreter.java @@ -19,10 +19,6 @@ public class OSTRAJavaInterpreter { final String MAIN_CLASS_NAME = "ostrava"; final String MAIN_METHOD_NAME = "rynek"; - final int FRAMES_NUMBER = 128; - final int FRAME_STACK_SIZE = 256; - final int MAX_HEAP_OBJECTS = 400; - final int END_RETURN_ADDRESS = -1; @@ -34,12 +30,12 @@ public class OSTRAJavaInterpreter { Natives natives; - public OSTRAJavaInterpreter(List compiledClasses) throws InterpreterException, LookupException { - this.stack = new Stack(FRAMES_NUMBER, FRAME_STACK_SIZE); + public OSTRAJavaInterpreter(List compiledClasses, int heap_size, int frame_number, int stack_size) throws InterpreterException, LookupException { + this.stack = new Stack(frame_number, stack_size); this.classPool = new ClassPool(compiledClasses); //Eden:Tenure 1:9 - this.heap = new GenerationHeap((int)(MAX_HEAP_OBJECTS * 0.1), (int)(MAX_HEAP_OBJECTS * 0.9), stack); + this.heap = new GenerationHeap((int)(heap_size * 0.1), (int)(heap_size * 0.9), stack); GenerationCollector gc = new GenerationCollector(stack, heap); this.heap.setGarbageCollector(gc); @@ -51,7 +47,7 @@ public OSTRAJavaInterpreter(List compiledClasses) throws InterpreterExcep } - public void run() throws InterpreterException, HeapOverflow { + public void run(List arguments) throws InterpreterException, HeapOverflow { InterpretedClass mainClass = null; Method mainMethod = null; @@ -62,9 +58,13 @@ public void run() throws InterpreterException, HeapOverflow { throw new InterpreterException("Main class not found. The name has to be '" + MAIN_CLASS_NAME + "'"); } - try { - mainMethod = mainClass.lookupMethod(MAIN_METHOD_NAME, classPool); - }catch (LookupException e) { + for (Method method: mainClass.getMethods()){ + if (method.getName().equals(MAIN_METHOD_NAME)){ + mainMethod = method; + } + } + + if (mainMethod == null){ throw new InterpreterException("Main method not found. The name has to be '" + MAIN_METHOD_NAME + "'"); } @@ -73,11 +73,16 @@ public void run() throws InterpreterException, HeapOverflow { //Create new frame for main method stack.newFrame(END_RETURN_ADDRESS, objectPointer, mainMethod); + //Pushing arguments to the main method local variables + pushArguments(stack.currentFrame(), mainMethod, arguments); + //Find instructions for main method int mainMethodPosition = ((InterpretedMethod)mainMethod).getInstructionPosition(); interpret(mainMethodPosition); } + + public void interpret(int startingPosition) throws InterpreterException, HeapOverflow { instructions.goTo(startingPosition); @@ -227,14 +232,9 @@ public void executeStringInstruction(Instruction instruction, Stack stack) throw String constant = constantPool.getConstant(constPosition); //Create array of chars and push it on stack - StackValue reference = heap.allocArray(constant.length()); - Array charArray = heap.loadArray(reference); - - for (int i = 0; i < constant.length(); i++){ - StackValue charValue = new StackValue(constant.charAt(i), StackValue.Type.Primitive); - charArray.set(i, charValue); - } + Array charArray = Converter.charArrayToArray(constant.toCharArray()); + StackValue reference = heap.alloc(charArray); stack.currentFrame().push(reference); } @@ -642,6 +642,35 @@ public void executeGoToInstruction(Instruction instruction, Stack stack) throws } + protected void pushArguments(Frame frame, Method mainMethod, List arguments) throws HeapOverflow { + List args = mainMethod.getArgs(); + int i = 0; + for (Type argType: args){ + if (i >= arguments.size()){ + break; + } + + StackValue argValue = null; + String stringArgValue = arguments.get(i); + + //Main method can get either number, char array or float as argument + //It depends on type of arguments in the main method + if (argType == Types.Number()) { + argValue = new StackValue(Integer.parseInt(stringArgValue), StackValue.Type.Primitive); + } else if (argType == Types.Float()){ + argValue = new StackValue(Float.parseFloat(stringArgValue)); + } else if (argType == Types.CharArray()){ + Array array = Converter.charArrayToArray(stringArgValue.toCharArray()); + argValue = heap.alloc(array);; + }else{ + new InterpreterException("Unsupported argument type '" + argType + "' in " + mainMethod); + } + + //0 reserved for this + frame.storeVariable(i+1, argValue); + i++; + } + } } diff --git a/src/cz/cvut/fit/ostrajava/Main.java b/src/cz/cvut/fit/ostrajava/Main.java index 69d8c67..13191ce 100644 --- a/src/cz/cvut/fit/ostrajava/Main.java +++ b/src/cz/cvut/fit/ostrajava/Main.java @@ -3,6 +3,7 @@ import java.io.*; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import cz.cvut.fit.ostrajava.Compiler.*; @@ -16,93 +17,21 @@ public class Main { public static void main(String[] args) throws Exception { - if (args.length == 0) { - System.out.println("Include filename in the arguments"); - return; - } - - List rootNodeList = parse(args); - - - List classList = new ArrayList<>(); - OSTRAJavaCompiler compiler = new OSTRAJavaCompiler(); - - //First stage - precompilation - for (Node node: rootNodeList){ - classList.addAll(compiler.precompile(node)); - } - - //Second stage - compilation - ClassPool classPool = new ClassPool(classList); - - classList.clear(); - - for (Node node: rootNodeList){ - classList.addAll(compiler.compile(node, classPool)); - } - - OSTRAJavaInterpreter interpreter = new OSTRAJavaInterpreter(classList); - interpreter.run(); - - } - - protected static List listAllFiles(String[] filenames){ - List files = new ArrayList<>(); - for (String fileName: filenames) { - File file = new File(fileName); - files.addAll(getFilesRecursively(file)); - } - - return files; - } - - protected static List getFilesRecursively(File file){ - List files = new ArrayList<>(); - - if (file.isDirectory()){ - File[] dirFiles = file.listFiles(); - for (File dirFile: dirFiles){ - files.addAll(getFilesRecursively(dirFile)); - } + String command =args[0]; + //Remove the command + String[] commandArgs = Arrays.copyOfRange(args, 1, args.length); + if (command.equals("run")){ + Run.exec(commandArgs); + }else if (command.equals("compile")){ + Compile.exec(commandArgs); }else{ - files.add(file); + System.out.println("use either 'run' or 'compile' command"); } - - return files; } - protected static List parse(String[] filenames) throws FileNotFoundException, ParseException { - Reader fr = null; - OSTRAJavaParser jp = null; - - List rootNodeList = new ArrayList<>(); - for (File file: listAllFiles(filenames)) { - - fr = new InputStreamReader(new FileInputStream(file)); - - if (jp == null){ - jp = new OSTRAJavaParser(fr); - }else{ - jp.ReInit(fr); - } - - try { - //Parse - jp.CompilationUnit(); - ASTCompilationUnit node = (ASTCompilationUnit) jp.rootNode(); - - rootNodeList.add(node); - } catch (ParseException e) { - System.out.println("Parsing exception in file " + file.getName()); - throw e; - } - } - - return rootNodeList; - } } diff --git a/src/cz/cvut/fit/ostrajava/Run.java b/src/cz/cvut/fit/ostrajava/Run.java new file mode 100644 index 0000000..695737e --- /dev/null +++ b/src/cz/cvut/fit/ostrajava/Run.java @@ -0,0 +1,109 @@ + +package cz.cvut.fit.ostrajava; + +import java.io.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import cz.cvut.fit.ostrajava.Compiler.*; +import cz.cvut.fit.ostrajava.Compiler.Class; +import cz.cvut.fit.ostrajava.Interpreter.ClassPool; +import cz.cvut.fit.ostrajava.Interpreter.OSTRAJavaInterpreter; +import cz.cvut.fit.ostrajava.Parser.*; + + +public class Run { + + public static void printHelp(){ + System.out.println("Pouziti: ostrajava \n"+ + "kaj moznosti muzu byt: \n" + + "-h velikost heap \n" + + "-f pocet framu \n" + + "-s velikost stacku ve framu \n" + ); + } + + public static void exec(String[] args) throws Exception + { + if (args.length == 0) { + printHelp(); + System.exit(0); + } + + List arguments = new ArrayList<>(Arrays.asList(args)); + + int heap_size = 1024; + int frame_count = 128; + int stack_size = 128; + + for (int i = 0; i < args.length-1; i ++) { + String param = args[i]; + String value = args[i+1]; + boolean isParam = false; + + if (param.equals("-h")){ + isParam = true; + heap_size = Integer.parseInt(value); + }else if (param.equals("-f")){ + isParam = true; + frame_count = Integer.parseInt(value); + }else if (param.equals("-s")){ + isParam = true; + stack_size = Integer.parseInt(value); + } + + if (isParam){ + arguments.remove(param); + arguments.remove(value); + } + } + + if (arguments.size() == 0){ + printHelp(); + System.exit(0); + } + + String directory = arguments.get(0); + arguments.remove(0); + + List classList = loadClassfiles(directory); + + OSTRAJavaInterpreter interpreter = new OSTRAJavaInterpreter(classList, heap_size, frame_count, stack_size); + interpreter.run(arguments); + + } + + public static List loadClassfiles(String directoryName) throws IOException { + File directory = new File(directoryName); + + List classList = new ArrayList<>(); + + if (directory.isDirectory()){ + File[] dirFiles = directory.listFiles(); + for (File dirFile: dirFiles){ + String extension = ""; + + int i = dirFile.getName().lastIndexOf('.'); + if (i > 0) { + extension = dirFile.getName().substring(i + 1); + } + + if (extension.equals(Compile.CLASS_TYPE_EXTENSION)) { + classList.add(Classfile.fromFile(dirFile)); + } + } + + }else{ + System.out.println("Please include directory of class files"); + System.exit(0); + } + + + return classList; + } + + + + +}