PageRenderTime 72ms CodeModel.GetById 40ms app.highlight 11ms RepoModel.GetById 19ms app.codeStats 1ms

/src/org/ooc/frontend/parser/LineParser.java

http://github.com/nddrylliog/ooc
Java | 113 lines | 98 code | 15 blank | 0 comment | 30 complexity | 158fc49cc467d748842f96d8ac672a5c MD5 | raw file
  1package org.ooc.frontend.parser;
  2
  3import org.ooc.frontend.model.BinaryOperation;
  4import org.ooc.frontend.model.ControlStatement;
  5import org.ooc.frontend.model.Expression;
  6import org.ooc.frontend.model.FunctionCall;
  7import org.ooc.frontend.model.Line;
  8import org.ooc.frontend.model.MemberCall;
  9import org.ooc.frontend.model.Module;
 10import org.ooc.frontend.model.Node;
 11import org.ooc.frontend.model.NodeList;
 12import org.ooc.frontend.model.Statement;
 13import org.ooc.frontend.model.VariableAccess;
 14import org.ooc.frontend.model.VariableDecl;
 15import org.ooc.frontend.model.tokens.Token;
 16import org.ooc.frontend.model.tokens.TokenReader;
 17import org.ooc.frontend.model.tokens.Token.TokenType;
 18import org.ubi.CompilationFailedError;
 19import org.ubi.SourceReader;
 20
 21public class LineParser {
 22	
 23	static int seedNumber = 1;
 24
 25	@SuppressWarnings({ "unchecked", "null" })
 26	public static boolean fill(Module module, SourceReader sReader, TokenReader reader, NodeList<Line> body) {
 27		
 28		int mark = reader.mark();
 29		
 30		reader.skipWhitespace();
 31		
 32		if(!reader.hasNext()) {
 33			reader.reset(mark);
 34			return false;
 35		}
 36		
 37		int mark2 = reader.mark();
 38		Node node = VariableDeclParser.parseMulti(module, sReader, reader);
 39		Statement statement = null;
 40		Line line = null;
 41		
 42		if(node != null) {
 43			if(node instanceof NodeList<?>) {
 44				for(VariableDecl vDecl : (NodeList<VariableDecl>) node) {
 45					statement = vDecl;
 46					line = new Line(vDecl);
 47					body.add(line);
 48				}
 49			} else {
 50				statement = (Statement) node;
 51				VariableDecl vDecl = (VariableDecl) node;
 52				line = new Line(vDecl);
 53				body.add(line);				
 54			}
 55		} else {
 56			reader.reset(mark2);
 57			statement = StatementParser.parse(module, sReader, reader);
 58			if(statement == null) {
 59				reader.reset(mark);
 60				return false;
 61			}
 62			line = new Line(statement);
 63			body.add(line);
 64		}
 65		
 66		while(reader.hasNext() && reader.peek().type == TokenType.DOT) {
 67			Expression expr = null;
 68			if(statement instanceof MemberCall) {
 69				MemberCall memberCall = (MemberCall) statement;
 70				expr = memberCall.getExpression();
 71				if(expr instanceof FunctionCall || expr instanceof BinaryOperation) {
 72					VariableDecl vdfe = new VariableDecl(null, "callroot" + (seedNumber++), expr, statement.startToken, null);
 73					body.addBefore(line, new Line(vdfe));
 74					expr = new VariableAccess(vdfe, expr.startToken);
 75					memberCall.setExpression(expr);
 76				}
 77			} else if(statement instanceof VariableDecl) {
 78				VariableDecl varDecl = (VariableDecl) statement;
 79				expr = new VariableAccess(varDecl, statement.startToken);
 80			} else if(statement instanceof Expression) {
 81				expr = (Expression) statement;
 82			} else {
 83				throw new CompilationFailedError(sReader.getLocation(reader.peek()),
 84						"Dots '.' for chain-calls should be used after expressions, not "
 85						+statement.getClass().getSimpleName()+"s.");
 86			}
 87			reader.skip();
 88			reader.skipWhitespace();
 89			Token startToken = reader.peek();
 90			FunctionCall otherCall = FunctionCallParser.parse(module, sReader, reader);
 91			if(otherCall == null) {
 92				throw new CompilationFailedError(sReader.getLocation(reader.peek()),
 93					"Expected function call after a dot '.'");
 94			}
 95			statement = new MemberCall(expr, otherCall, startToken);
 96			body.add(new Line(statement));
 97		}
 98		
 99		if(!(statement instanceof ControlStatement)) {
100			Token next = reader.peek();
101			if(next.type != TokenType.LINESEP && next.type != TokenType.CLOS_BRACK && next.type != TokenType.CLOS_PAREN) {
102				throw new CompilationFailedError(sReader.getLocation(next),
103						"Missing semi-colon at the end of a line (got a "+next+" instead)");
104			}
105			if(next.type == TokenType.LINESEP) reader.skip();
106		}
107		
108		return true;
109		
110	}
111
112	
113}