Skip to content

Instantly share code, notes, and snippets.

@exerro
Created September 20, 2017 13:15
Show Gist options
  • Save exerro/d0b41344db5707d4606df69ef43ea316 to your computer and use it in GitHub Desktop.
Save exerro/d0b41344db5707d4606df69ef43ea316 to your computer and use it in GitHub Desktop.
package Flux;
import java.util.ArrayList;
import parsing.Position;
public abstract class AST {
public static enum NodeType {
Statement,
Expression,
Definition,
Block
}
public static enum StatementType {
IfStatement,
WhileLoop,
RepeatLoop,
ForLoop,
ForeachLoop
}
public final NodeType type;
public final Position position;
public AST parent;
public ArrayList<AST> children;
public AST(NodeType type, Position position) {
this.type = type;
this.position = position;
children = new ArrayList<AST>();
}
private AST addChild(AST child) {
children.add( child );
return child;
}
public AST replaceChild(AST child, AST newChild) {
children.set( children.indexOf( child ), newChild );
return newChild;
}
public class Statement extends AST {
public final StatementType statementType;
public Statement( StatementType type, Position position ) {
super( NodeType.Statement, position );
this.statementType = type;
}
public class ConditionalStatement extends Statement {
public ConditionalStatement( StatementType type, Position position, AST condition, AST block ) {
super( type, position );
}
AST getCondition() {
return children.get( 0 );
}
AST getBlock() {
return children.get( 1 );
}
}
public class IfStatement extends ConditionalStatement {
public IfStatement( Position position, AST condition, AST block, AST elseBlock ) {
super( StatementType.IfStatement, position, condition, block );
addChild( condition );
addChild( block );
if (elseBlock != null) addChild( elseBlock );
}
AST getElseBlock() {
return children.size() == 2 ? null : children.get( 2 );
}
}
}
}
package parsing;
public class Position {
public final Source source;
public final int line1;
public final int line2;
public final int char1;
public final int char2;
public final int indentation;
public Position(Source source, int line1, int line2, int char1, int char2, int indentation) {
this.source = source;
this.line1 = line1;
this.line2 = line2;
this.char1 = char1;
this.char2 = char2;
this.indentation = indentation;
}
public Position after(String s) {
int line = line2;
int character = char2;
int indentation = this.indentation;
Boolean newline = false;
for (char c : s.toCharArray()) {
switch (c) {
case '\n':
indentation = 0;
line++;
newline = true;
break;
case ' ': case '\t':
if (newline) indentation++;
character++;
break;
default:
newline = false;
character++;
break;
}
}
return at( source, line, character, indentation );
}
public Position after(int n) {
return at( source, line2, char2 + n, indentation );
}
public Position extend(int n) {
return new Position( source, line1, line2, char1, char2 + n, indentation );
}
public Position to(Position p) {
return new Position( source, line1, char1, p.line2, p.char2, Math.min( indentation, p.indentation ) );
}
public Boolean follows(Position p) {
return p.source == source && p.line1 == line2 && p.char1 == char2 + 1;
}
public static Position at(Source source, int line, int character, int indentation) {
return new Position( source, line, line, character, character, indentation );
}
public static Position at(Source source, int line, int character, int length, int indentation) {
return new Position( source, line, line, character, character + length - 1, indentation );
}
}
package parsing;
import java.io.*;
import Flux.WarningLogger;
import Flux.WarningLogger.WarningCode;
public class Source {
public final String name;
public final String path;
public Source(String name, String path) {
this.name = name;
this.path = path;
}
private FileInputStream getStream() throws WarningLogger.Warning {
try {
return new FileInputStream( this.path );
}
catch (FileNotFoundException e) {
WarningLogger.logger.error(WarningLogger.WarningCode.SourceStreamOpenFailure, "Failed to open file stream for source '" + this.name + "': " + e.toString() );
}
// this will never execute?
return null;
}
public String getContent() throws WarningLogger.Warning {
try {
FileInputStream stream = getStream();
BufferedReader buf = new BufferedReader(new InputStreamReader( stream ));
String line = buf.readLine();
StringBuilder sb = new StringBuilder();
while(line != null){
sb.append(line).append("\n");
line = buf.readLine();
}
return sb.toString();
}
catch (IOException e) {
WarningLogger.logger.error( WarningLogger.WarningCode.SourceFileReadFailure, "Failed to read content of file for source '" + name + "'" );
}
return "";
}
public String getLine(int line) throws WarningLogger.Warning {
FileInputStream stream = getStream();
String ret = "";
try {
while (line > 1) {
int b = stream.read();
if (b == -1) break;
if (b == '\n') line--;
}
while (true) {
int b = stream.read();
if (b == -1 || b == '\n') break;
ret += (char) b;
}
return ret;
}
catch (IOException e) {
WarningLogger.logger.error( WarningCode.SourceLineReadFailure, "Failed to read line " + line + " of source '" + name + "': " + e.toString() );
}
return "";
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment