~otheb/i

03ac0a2030f79e90c7d3ca99ccb1558b959d6ec7 — Olie Ayre 4 years ago 7d89931
Finish parsing code
5 files changed, 226 insertions(+), 11 deletions(-)

M SYNTAX
M compiler.d
M i.d
M model/statements.d
M test/test.i
M SYNTAX => SYNTAX +1 -1
@@ 135,7 135,7 @@ While:
Until:
	until [!] SingleFnParam Block
Match:
	match FnParams { [MatchBlock...] FinalMatchBlock }
	match SingleFnParam { [MatchBlock...] FinalMatchBlock }
MatchBlock:
	Ex Block
FinalMatchBlock:

M compiler.d => compiler.d +2 -2
@@ 16,12 16,12 @@ ubyte[] compile( string code )
	                 .filter!( t => t.type != typeid(NonToken) ).array ;
	// parser stage
	File ast = parse( tokens ) ;
	//log.raw( "\n" , ast , "\n" ) ;
	
	if ( ast.length < tokens.length ) {
		if ( furthestErr !is null ) throw furthestErr ;
		else perror( tokens[ast.length] ) ;
	}
	// semantic analysis stage


	// return nothing for now as we're not generating code
	return [] ;

M i.d => i.d +1 -1
@@ 13,7 13,7 @@ void main( string[] args ) {
	// all args are files to compile
	// file.i -> file.o

	log.level = LogLevel.Debug ;
	log.level = LogLevel.Warn ;

	// error on no files
	if ( args.length == 1 ) {

M model/statements.d => model/statements.d +198 -2
@@ 2,14 2,17 @@ module model.statements ;

import model   ;
import logging ;
import err     ;

import util.parsing ;

import std.variant ;

alias Statement = Algebraic!( Ex , VarDef , FlowControl ) ;
alias Statement = Algebraic!( VarDef , AliasDef , Ex , FlowControl ,
                              DebugStatement , If , Foreach , WhileUntil ,
                              Match , Defer , With ) ;
TypeInfo[] StatementSemicolons = [
	typeid(Ex) , typeid(VarDef) , typeid(FlowControl)
	typeid(VarDef) , typeid(AliasDef) , typeid(Ex) , typeid(FlowControl)
] ;

class FlowControl : AstBase {


@@ 35,3 38,196 @@ class FlowControl : AstBase {
		argument = a ;
	}
}

class DebugStatement : AstBase {
	Block body = null ;

	this( Token[] buffer ) {
		log.dbug!"parser"( "Trying to create a DebugStatement" ) ;
		startLoc( buffer ) ;
		// debug
		this.token!Keyword( buffer , [ "debug" ] ) ;
		// Block
		body = this.node!Block( buffer ) ;
		endLoc( buffer ) ;
		log.dbug!"parser"( "Created a DebugStatement" ) ;
	}
}

class If : AstBase {
	bool  invert    = false ;
	Ex    condition = null  ;
	Block body      = null  ;
	bool  continues = false ;
	Block elseBody  = null  ;
	If    elseIf    = null  ;

	this( Token[] buffer ) {
		log.dbug!"parser"( "Trying to create an If" ) ;
		startLoc( buffer ) ;
		// if
		this.token!Keyword( buffer , [ "if" ] ) ;
		// [!]
		invert = this.opt( { this.token!Keyword( buffer , [ "!" ] ) ; } ) ;
		// (
		this.token!Keyword( buffer , [ "(" ] ) ;
		// Ex
		condition = this.node!Ex( buffer ) ;
		// )
		this.token!Keyword( buffer , [ ")" ] ) ;
		endLoc( buffer ) ;
		// Block
		body = this.node!Block( buffer ) ;
		this.opt( {
			// else
			this.token!Keyword( buffer , [ "else" ] ) ;
			if ( ! this.opt( {
				continues = false ;
				// Block
				elseBody = this.node!Block( buffer ) ;
			} , {
				continues = true ;
				// If
				elseIf = this.node!If( buffer ) ;
			} ) ) perror( buffer[length].location ,
			              "Expected either Block or If" ) ;
		} ) ;
		log.dbug!"parser"( "Created an If" ) ;
	}
}

class Foreach : AstBase {
	bool         reverse = false ;
	FnParamDef[] params  = []    ;
	Ex           source  = null  ;
	Block        body    = null  ;

	this( Token[] buffer ) {
		log.dbug!"parser"( "Trying to create a Foreach" ) ;
		startLoc( buffer ) ;
		// {foreach, rforeach}
		reverse = this.token!Keyword( buffer , [ "foreach" , "rforeach" ] )
			.content == "rforeach" ;
		// (
		this.token!Keyword( buffer , [ "(" ] ) ;
		// SimpleFnParamDefs
		this.list( buffer , params ~= this.node!FnParamDef( buffer , true ) ) ;
		// in
		this.token!Keyword( buffer , [ "in" ] ) ;
		// Ex
		source = this.node!Ex( buffer ) ;
		// )
		this.token!Keyword( buffer , [ ")" ] ) ;
		endLoc( buffer ) ;
		// Block
		body = this.node!Block( buffer ) ;
		log.dbug!"parser"( "Created a Foreach" ) ;
	}
}

class WhileUntil : AstBase {
	bool  invert    = false ;
	Ex    condition = null  ;
	Block body      = null  ;

	this( Token[] buffer ) {
		log.dbug!"parser"( "Trying to create a WhileUntil" ) ;
		// {while, until}
		invert = this.token!Keyword( buffer , [ "while" , "until" ] )
			.content == "until" ;
		// [!]
		invert = this.opt( { this.token!Keyword( buffer , [ "!" ] ) ; } )
			+ invert == 1 ;
		// (
		this.token!Keyword( buffer , [ "(" ] ) ;
		// Ex
		condition = this.node!Ex( buffer ) ;
		// )
		this.token!Keyword( buffer , [ ")" ] ) ;
		endLoc( buffer ) ;
		// Block
		body = this.node!Block( buffer ) ;
		log.dbug!"parser"( "Created a WhileUntil" ) ;
	}
}

class Match : AstBase {
	Ex           source     = null ;
	MatchBlock[] blocks     = []   ;
	Block        finalBlock = null ;

	this( Token[] buffer ) {
		log.dbug!"parser"( "Trying to create a Match" ) ;
		startLoc( buffer ) ;
		// match
		this.token!Keyword( buffer , [ "match" ] ) ;
		// (
		this.token!Keyword( buffer , [ "(" ] ) ;
		// Ex
		source = this.node!Ex( buffer ) ;
		// )
		this.token!Keyword( buffer , [ ")" ] ) ;
		endLoc( buffer ) ;
		// {
		this.token!Keyword( buffer , [ "{" ] ) ;
		// [MatchBlock...]
		this.many( blocks ~= this.node!MatchBlock( buffer ) ) ;
		// else
		this.token!Keyword( buffer , [ "else" ] ) ;
		// Block
		finalBlock = this.node!Block( buffer ) ;
		// }
		this.token!Keyword( buffer , [ "}" ] ) ;
		log.dbug!"parser"( "Created a Match" ) ;
	}
}

class MatchBlock : AstBase {
	Ex    condition = null ;
	Block body      = null ;

	this( Token[] buffer ) {
		log.dbug!"parser"( "Trying to create a MatchBlock" ) ;
		startLoc( buffer ) ;
		condition = this.node!Ex( buffer ) ;
		body = this.node!Block( buffer ) ;
		log.dbug!"parser"( "Created a MatchBlock" ) ;
	}
}

class Defer : AstBase {
	Block body = null ;

	this( Token[] buffer ) {
		log.dbug!"parser"( "Trying to create a Defer" ) ;
		startLoc( buffer ) ;
		// defer
		this.token!Keyword( buffer , [ "defer" ] ) ;
		// Block
		body = this.node!Block( buffer ) ;
		endLoc( buffer ) ;
		log.dbug!"parser"( "Created a Defer" ) ;
	}
}

class With : AstBase {
	VarDef varDef = null ;
	Block  body   = null ;

	this( Token[] buffer ) {
		log.dbug!"parser"( "Trying to create a With" ) ;
		startLoc( buffer ) ;
		// with
		this.token!Keyword( buffer , [ "with" ] ) ;
		// (
		this.token!Keyword( buffer , [ "(" ] ) ;
		// VarDef
		varDef = this.node!VarDef( buffer ) ;
		// )
		this.token!Keyword( buffer , [ ")" ] ) ;
		endLoc( buffer ) ;
		// Block
		body = this.node!Block( buffer ) ;
		log.dbug!"parser"( "Created a With" ) ;
	}
}

M test/test.i => test/test.i +24 -5
@@ 30,6 30,25 @@ void main() {
	// statements
	prln( s ) ;
	return ;
	debug {
		log::dbug( "this is " , "my debugging message" ) ;
	}
	if ( s == "aaaa" ) { what
	} else if ! ( true ) { the
	} else { f }
	foreach ( x , i in mybigarray ) {
		prln( "item " , i , " is " , x ) ;
	}
    while ( true ) { }
    until ! ( true ) { }
    match ( 3 ) {
        1 { what }
        2 { the }
        3 { f }
        else { wheeeee }
    }
    defer { return 1 }
    with ( int x = 4 ) { x.prln() }
}
i32 add( i32 x , i32 y ) { x + y }



@@ 73,16 92,16 @@ template MyTemplate( A , B , string c ) {

// debug
debug {
    i32 dbug = 10 ;
	i32 dbug = 10 ;
}

// version
version ( MyVersion ) {
    version = Feature1 ;
    version = Feature2 ;
	version = Feature1 ;
	version = Feature2 ;

    void feature1() {}
    void feature2() {}
	void feature1() {}
	void feature2() {}
}

// applied example: algebraic type