@@ 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 [] ;
@@ 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" ) ;
+ }
+}
@@ 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