diff --git a/version2.0/nasal_enum.h b/version2.0/nasal_enum.h index 9051872..d9331a3 100644 --- a/version2.0/nasal_enum.h +++ b/version2.0/nasal_enum.h @@ -159,6 +159,7 @@ enum parse_error_type error_token_in_block, // when a token should not be the begin of a statement in block lack_semi, + lack_id, definition_lack_id, // lack identifier definition_lack_equal, // lack '=' when not getting ';' @@ -206,6 +207,8 @@ void print_parse_error(int error_type,int line,int error_token_type=__stack_end) break; case lack_semi: std::cout<get_token(); + ++cnt;// get '(' + + this->get_token(); + ++cnt; + if(this_token.type==__id) + { + + } + + + return ret; +} + bool nasal_parse::check_comma_in_curve() { // when generating multi_assignment @@ -537,6 +557,8 @@ abstract_syntax_tree nasal_parse::multive_calculation() abstract_syntax_tree calc_node; abstract_syntax_tree tmp_node; this->get_token(); + // be careful that unary calculation and assignment cannot be used together + // such as: -a=1; this is incorrect use. if((this_token.type==__sub_operator) || (this_token.type==__nor_operator)) { calc_node.set_node_line(this_token.line); @@ -546,7 +568,7 @@ abstract_syntax_tree nasal_parse::multive_calculation() null_node.set_node_type(__number); null_node.set_var_number("0"); calc_node.add_children(null_node); - calc_node.add_children(assign_calculation()); + calc_node.add_children(scalar_generate()); } else { @@ -571,7 +593,7 @@ abstract_syntax_tree nasal_parse::multive_calculation() null_node.set_node_type(__number); null_node.set_var_number("0"); calc_node.add_children(null_node); - calc_node.add_children(assign_calculation()); + calc_node.add_children(scalar_generate()); } else { @@ -676,8 +698,8 @@ abstract_syntax_tree nasal_parse::scalar_generate() if(this_token.type==__colon) { scalar_para=false; - this->push_token(); - this->push_token(); + this->push_token();// colon + this->push_token();// identifier while(this_token.type!=__right_curve) { abstract_syntax_tree special_para_node; @@ -721,10 +743,12 @@ abstract_syntax_tree nasal_parse::scalar_generate() } else { - this->push_token(); - this->push_token(); + this->push_token();// not colon + this->push_token();// identifier } } + else + this->push_token();// if not identifier then push in if(scalar_para) while(this_token.type!=__right_curve) { @@ -863,7 +887,7 @@ abstract_syntax_tree nasal_parse::hash_generate() } hash_member_node.add_children(calculation()); this->get_token(); - if(this_token.type!=__comma && this_token.type!=__right_brace) + if((this_token.type!=__comma) && (this_token.type!=__right_brace)) { ++error; print_parse_error(hash_gen_lack_end,this_token.line,this_token.type); @@ -896,7 +920,7 @@ abstract_syntax_tree nasal_parse::vector_generate() { vector_node.add_children(calculation()); this->get_token(); - if(this_token.type!=__comma && this_token.type!=__right_bracket) + if((this_token.type!=__comma) && (this_token.type!=__right_bracket)) { ++error; print_parse_error(vector_gen_lack_end,this_token.line,this_token.type); @@ -1096,7 +1120,9 @@ abstract_syntax_tree nasal_parse::loop_expr() loop_main_node.set_node_type(this_token.type); if(this_token.type==__for) { - ; + this->get_token(); + if(this_token.type==__semi) + this->push_token(); } else if(this_token.type==__while) { @@ -1116,7 +1142,44 @@ abstract_syntax_tree nasal_parse::loop_expr() } else { - ; + // forindex + // foreach + this->get_token();// '(' + if(this_token.type!=__left_curve) + { + ++error; + print_parse_error(lack_left_curve,this_token.line,this_token.type); + } + this->get_token();// 'var' + if(this_token.type!=__var) + this->push_token(); + this->get_token();// id + if(this_token.type!=__id) + { + ++error; + print_parse_error(lack_id,this_token.line); + } + else + { + abstract_syntax_tree id_node; + id_node.set_node_line(this_token.line); + id_node.set_node_type(__id); + id_node.set_var_name(this_token.str); + loop_main_node.add_children(id_node); + } + this->get_token();// ';' + if(this_token.type!=__semi) + { + ++error; + print_parse_error(lack_semi,this_token.line); + } + loop_main_node.add_children(scalar_generate());// get hash/vector or keys(hash/vector) + this->get_token(); + if(this_token.type!=__right_curve) + { + ++error; + print_parse_error(lack_right_curve,this_token.line,this_token.type); + } } statements_block_generate(loop_main_node); return loop_main_node; diff --git a/version2.0/parse.ebnf b/version2.0/parse.ebnf index e3303e2..7edb2c6 100644 --- a/version2.0/parse.ebnf +++ b/version2.0/parse.ebnf @@ -26,7 +26,6 @@ | | | -| | '(' ')' | { ('[' { ','} ']') | ('[' ':' [] ']') | ('.' ) | ('(' { ','} ')') | ('(' { ':' ','} ')') } ; @@ -55,13 +54,9 @@ = '=' | '(' { ','} ')' '=' ( | '(' { ','} ')') +| '(' { ','} ')' '=' ( | '(' { ','} ')') ; - = - -; - = - -; + = ('=' | '+=' | '-=' | '*=' | '/=' | '~=') | '(' { ','} ')' ('=' | '+=' | '-=' | '*=' | '/=' | '~=') ( | '(' { ','} ')') @@ -82,12 +77,12 @@ ; (* in forindex and foreach the scalar and definition cannot be lacked*) = - '(' ';' ')' [';'] -| '(' ';' ')' '{' { ';'} '}' + '(' ( )|() ';' ')' [';'] +| '(' ( )|() ';' ')' '{' { ';'} '}' ; = - '(' ';' ')' [';'] -| '(' ';' ')' '{' { ';'} '}' + '(' ( )|() ';' ')' [';'] +| '(' ( )|() ';' ')' '{' { ';'} '}' ; = {} [] diff --git a/version2.0/test/choice.nas b/version2.0/test/choice.nas new file mode 100644 index 0000000..f01c351 --- /dev/null +++ b/version2.0/test/choice.nas @@ -0,0 +1,28 @@ + +var condition_true=1; +var condition_false=0; +if(condition_true) +{ + var a=1; +} +else if(!condition_false) +{ + var b=1; +} +elsif(!condition_true and condition_false) +{ + print("impossible"); +} +else +{ + var c=1; +} + +if(condition_true) + var a=1; +else if(!condition_false) + var b=1; +elsif(!condition_true and condition_false) + print("impossible"); +else + var c=1; \ No newline at end of file diff --git a/version2.0/test/final.nas b/version2.0/test/final.nas new file mode 100644 index 0000000..ac5d13c --- /dev/null +++ b/version2.0/test/final.nas @@ -0,0 +1,210 @@ +var smartScreen = canvas.new({ + "name": "smartScreen", # The name is optional but allow for easier identification + "size": [2048, 2048], # Size of the underlying texture (should be a power of 2, required) [Resolution] + "view": [768, 768], # Virtual resolution (Defines the coordinate system of the canvas [Dimensions] + # which will be stretched the size of the texture, required) + "mipmapping": 1 # Enable mipmapping (optional) +}); + +smartScreen.addPlacement({"node": "screen", "texture": "screen.jpeg"}); +var group = smartScreen.createGroup(); + +# Create a text element and set some values +var text = group.createChild("text", "optional-id-for element") + .setTranslation(10, 20) # The origin is in the top left corner + .setAlignment("left-center") # All values from osgText are supported (see $FG_ROOT/Docs/README.osgtext) + .setFont("LiberationFonts/LiberationSans-Regular.ttf") # Fonts are loaded either from $AIRCRAFT_DIR/Fonts or $FG_ROOT/Fonts + .setFontSize(14, 1.2) # Set fontsize and optionally character aspect ratio + .setColor(1,0,0) # Text color + .setText("This is a text element"); +text.hide(); +text.setText("SELF TEST NORMAL").show(); + + + +var ui_root = smartScreen.createGroup(); +var vbox = canvas.VBoxLayout.new(); +smartScreen.setLayout(vbox); + + +var button_onl = canvas.gui.widgets.Button.new(ui_root, canvas.style, {}).setText("Online OSM").listen("clicked", func showOnlineMap()); +var button_offl = canvas.gui.widgets.Button.new(ui_root, canvas.style, {}).setText("Offline OSM").listen("clicked", func showOfflineMap()); +button_onl.setSizeHint([32, 128]); +button_offl.setSizeHint([32, 128]); + +var label = canvas.gui.widgets.Label.new(ui_root, canvas.style, {}); + +var button_box = canvas.HBoxLayout.new(); +button_box.addItem(button_onl); +button_box.addItem(button_offl); +button_box.addItem(label); +button_box.addStretch(1); + +vbox.addItem(button_box); +vbox.addStretch(1); + + +var showOnlineMap = func(){ + TestMap.show(); + g.hide(); + label.setText("Online Mode"); +} + + +var showOfflineMap = func(){ + TestMap.hide(); + g.show(); + label.setText("Offline Mode"); +} + + +# Online Map using MapStructure +var TestMap = smartScreen.createGroup().createChild("map"); +TestMap.setTranslation(smartScreen.get("view[0]")/2,smartScreen.get("view[1]")/2); + + +var ctrl_ns = canvas.Map.Controller.get("Aircraft position"); +var source = ctrl_ns.SOURCES["map-dialog"]; +if (source == nil) { + # TODO: amend + var source = ctrl_ns.SOURCES["map-dialog"] = { + getPosition: func subvec(geo.aircraft_position().latlon(), 0, 2),# ? ? ? + getAltitude: func getprop('/position/altitude-ft'), + getHeading: func { + if (me.aircraft_heading) + getprop('/orientation/heading-deg'); + else + 0; + }, + aircraft_heading: 1, + }; +} +setlistener("/sim/gui/dialogs/map-canvas/aircraft-heading-up", func(n){source.aircraft_heading = n.getBoolValue();}, 1); +TestMap.setController("Aircraft position", "map-dialog"); +TestMap.setRange(1); + +var r = func(name,vis=1,zindex=nil){return caller(0)[0];}; +# TODO: we'll need some z-indexing here, right now it's just random + +foreach(var type; [r('APS')] ){ + TestMap.addLayer(factory: canvas.SymbolLayer, type_arg: type.name, visible: type.vis, priority: 2); +} + +foreach(var type; [ r('OSM')]) { + TestMap.addLayer(factory: canvas.OverlayLayer, + type_arg: type.name, + visible: type.vis, + priority: 1); +} + + +TestMap.hide(); + +# Offline map + +var g = smartScreen.createGroup(); +var zoom = 15; +var type = "intl"; +var tile_size = 256; + + +var changeZoom = func(d) +{ + zoom = math.max(2, math.min(19, zoom + d)); + updateTiles(); +} + +# http://polymaps.org/docs/ +# https://github.com/simplegeo/polymaps +# https://github.com/Leaflet/Leaflet + +var maps_base = getprop("/sim/fg-home") ~ '/cache/maps'; + +var makePath = +string.compileTemplate(maps_base ~ '/osm-{type}/{z}/{x}/{y}.jpg'); +var num_tiles = [4, 4]; + +var center_tile_offset = [(num_tiles[0]-1)/2, (num_tiles[1]-1)/ 2]; + +# simple aircraft icon at current position/center of the map +g.createChild("path") + .moveTo( tile_size*center_tile_offset[0]-10, tile_size*center_tile_offset[1]) + .horiz(20) + .move(-10,-10) + .vert(20) + .set("stroke", "red") + .set("stroke-width", 2) + .set("z-index", 1); + +# initialize the map by setting up +# a grid of raster images + +var tiles = setsize([], num_tiles[0]); +for(var x=0; x0? x:0;})(12); +(func{print("hello world");})(); +(((func(x){return 1.0/math.exp(x);})))(0); + +# flexible definition & assignment +var (r,g,b)=[0x00,0x10,0xff]; +(var r,g,b)=[0x00,0x10,0xff]; +var color=[0x00,0x10,0xff]; +var (r,g,b)=color; +(var r,g,b)=color; +(r,g,b)=(b,g,r); +(number_1,number_2)=(number_2,number_1); + +# calculation +1+1; +1+1-2+3-4+5-6; +1+1*8-9/3; +1*-1; +1*(1+2*(3+4*(5+6*(7+8*(9+10/(1+1)))))); +((-1*2+9))/7-1; +((({num:2})))["num"]*2*2*2; +((((([0,1,2])[0:2]))[0:2]))[1]-1; +(((((((((((((((((((1+1+2+3+5)+8))+13)))+21))))+34)))))+55))))*89; +number_1*(number_2+number_3)/90-number_4; +(func test_func)()-1; +hash_3.member_3+(func {return {what:"i don't tell you.",case_small:80,case_large:100}})["case_large"]/10; +-1*10+5 or 10-10; +nil and 1+7*8; +(number_1 or number_2) and (number_3 or number_4-number_4*1); +[0,1,4,3,2][4]*2-4+1*2*2*2*2*2/8; +{num:0}.num or {what_is_the_secret_of_universe:42}["what_is_the_secret_of_universe"]; +"123"~"456"-123456*2/2; \ No newline at end of file