diff --git a/version2.0/lib/bits.nas b/version2.0/lib/bits.nas index 7df07b8..07b791e 100644 --- a/version2.0/lib/bits.nas +++ b/version2.0/lib/bits.nas @@ -1,5 +1,5 @@ # nasal lib bits.nas -# 2020/2/6 +# 2020/2/8 # this file is used to avoid name confliction # and is used to avoid name undefined # before running this file will be translated to abstract syntax tree @@ -7,8 +7,34 @@ var bits= { - fld:func(){}, - sfld:func(){}, - setfld:func(){}, - buf:func(){}, + # Interpreting the string str as bits, + # returns the bitfield of the specified length starting at startbit. + # Interprets the result as an unsigned integer. + # The bit order is bytewise big endian: The 0th bit is the high bit of the first byte. + # The last bit is the low bit of the last byte in the string. + fld:func(__string,startbit,length) + { + var call_built_in_bitcalc=func(__str,__start,__len){}; + return call_built_in_bitcalc(__string,startbit,length); + }, + # As bits.fld(), but interprets the result as a 2's complement signed value. + sfld:func(__string,startbit,length) + { + var call_built_in_sbitcalc=func(__str,__start,__len){}; + return call_built_in_sbitcalc(__string,startbit,length); + }, + # Sets the specified value into the bit string at the specified position. + # The string must be mutable: either the result of a runtime concatenation (the ~ operator) or a call to bits.buf()(see below). + # Attempts to modify immutable strings (e.g. compile time constants) will produce a runtime error. + setfld:func(__string,startbit,length,value) + { + var call_built_in_setbit=func(__str,__start,__len,__val){}; + return call_built_in_setbit(__string,startbit,length,value); + }, + # Returns a zero-filled mutable string of the specified length. + buf:func(length) + { + var call_built_in_null_string_gen=func(__len){}; + return call_built_in_null_string_gen(length); + }, }; \ No newline at end of file diff --git a/version2.0/lib/io.nas b/version2.0/lib/io.nas index 7d7d151..7339bb1 100644 --- a/version2.0/lib/io.nas +++ b/version2.0/lib/io.nas @@ -1,5 +1,5 @@ # nasal lib io.nas -# 2020/2/6 +# 2020/2/8 # this file is used to avoid name confliction # and is used to avoid name undefined # before running this file will be translated to abstract syntax tree @@ -7,42 +7,78 @@ var io= { - open:func(){}, - close:func(){}, - read:func(){}, - write:func(){}, - seek:func(){}, - tell:func(){}, - readln:func(){}, - stat:func(){}, -}; - -var input=func(filename="") -{ - if(filename=="") - return __system_call_cpp_istream(); - else - return __system_call_cpp_ifstream(filename); + # Opens the file with the specified mode (as per ANSI fopen()) and returns a ghost object representing the filehandle. + # Failures are thrown as runtime errors as per die(). + open:func(filename,mode="r") + { + var call_c_fopen=func(__file,__mode){}; + return call_c_fopen(filename,mode); + }, + # Closes the specified file as per ANSI fclose(). + close:func(filehandle) + { + var call_c_fclose=func(__filehandle){}; + call_c_fclose(filehandle); + return; + }, + # Attempts to read length bytes from the filehandle into the beginning of the mutable string buf. + # Failures (including overruns when length > size(buf)) are thrown as runtime errors as per die(). + # Returns the number of bytes successfully read. + read:func(filehandle,buf,length) + { + var call_c_read=func(__filehandle,__buf,__len){}; + return call_c_read(filehandle,buf,length); + }, + # Attempts to write the entirety of the specified string to the filehandle. + # Failures are thrown as runtime errors as per die(). + # Returns the number of bytes successfully written. + write:func(filehandle,str) + { + var call_c_write=func(__filehandle,__str){}; + return call_c_write(filehandle,str); + }, + # As ANSI fseek(). + # Attempts to seek to the specified position based on the whence value + # (which must be one of io.SEEK_SET,io.SEEK_END, or io.SEEK_CUR) + SEEK_SET:1, + SEEK_CUR:2, + SEEK_END:3, + seek:func(filehandle,position,whence) + { + var call_c_seek=func(__filehandle,__position,__whence){}; + call_c_seek(filehandle,position,whence); + return; + }, + # Returns the current seek position of the filehandle. + tell:func(filehandle) + { + var call_c_tell=func(__filehandle){}; + return call_c_tell(filehandle); + }, + # Reads and returns a single text line from the filehandle. + # Interprets both "\n" and "\r\n" as end of line markers, + # and does not include the "\r" or "\n" bytes in the returned string. + # End offile or error is signaled by returning nil. + readln:func(filehandle) + { + var call_builtin_c_getline=func(__filehandle){}; + return call_builtin_c_getline(filehandle); + }, + # Calls unix or win32 stat() on the specified file name and + # returns a seven element array whose contents are, + # in order: dev, ino, mode,nlink, uid, gid, rdef, size, atime, mtime, ctime. + # Errors are signaled as exceptions as per die(). + stat:func(filename) + { + var call_builtin_stat=func(__filename){}; + return call_builtin_stat(filename); + }, }; var print=func(dyn...) { + var __system_call_c_std_puts=func(__str){}; forindex(var i;dyn) - __system_call_c_puts(dyn[i]); + __system_call_c_std_puts(dyn[i]); return nil; -}; - -var fprint=func(arr,filename="") -{ - if(filename=="") - { - print("__fprint didn't get a correct file name\n"); - return false; - } - else - { - __system_call_cpp_ofstream(arr,filename); - return true; - } - return; -} \ No newline at end of file +}; \ No newline at end of file diff --git a/version2.0/lib/math.nas b/version2.0/lib/math.nas index e3b7e9f..a9108f0 100644 --- a/version2.0/lib/math.nas +++ b/version2.0/lib/math.nas @@ -1,5 +1,5 @@ # nasal lib math.nas -# 2020/2/6 +# 2020/2/8 # this file is used to avoid name confliction # and is used to avoid name undefined # before running this file will be translated to abstract syntax tree @@ -7,25 +7,46 @@ var math= { + # Euler's constant e:2.7182818284590452354, pi:3.14159265358979323846, + # Returns the sine of the single argument sin:func(x) { - var call_inline_sin=func(x){}; + var call_inline_sin=func(__x){}; return call_inline_sin(x); }, + # Returns the cosine of the single argument cos:func(x) { - var call_inline_cos=func(x){}; + var call_inline_cos=func(__x){}; return call_inline_cos(x); }, + # you know what the f*ck this is tan:func(x){return me.sin(x)/me.cos(x);}, + # Returns e (Euler's constant) raised to the power specified by the single argument exp:func(x) { - var call_inline_pow=func(num,x){}; + var call_inline_pow=func(__num,__x){}; return call_inline_pow(me.e,x); }, - ln:func(){}, - sqrt:func(){}, - atan2:func(){}, + # Returns the natural logarithm of the single argument. + ln:func(x) + { + var call_inline_cpp_math_ln=func(__x){}; + return call_inline_cpp_math_ln(x); + }, + # Returns the square root of the single argument. + sqrt:func(x) + { + var call_inline_cpp_math_sqrt=func(__x){}; + return call_inline_cpp_math_sqrt(x); + }, + # Returns the arctangent of y/x, with the correct sign for the quadrant. + # Wraps the ANSI C function of the same name. + atan2:func(x,y) + { + var call_inline_cpp_atan2=func(__num1,__num2){}; + return call_inline_cpp_atan2(x,y); + }, }; \ No newline at end of file diff --git a/version2.0/nasal_enum.h b/version2.0/nasal_enum.h index 31a3e87..d11d255 100644 --- a/version2.0/nasal_enum.h +++ b/version2.0/nasal_enum.h @@ -179,7 +179,9 @@ enum parse_error_type special_call_func_lack_colon, call_func_lack_comma, call_hash_lack_id, // lack identifier when calling a hash + call_vector_wrong_comma, // wrong use of comma like this: id[0,4:6,7,] (the last comma is incorrect here) call_vector_lack_bracket, // lack ']' when calling a vector + call_vector_wrong_token, // get wrong token when calling a vector vector_gen_lack_end, // lack ',' or ')' when generating a vector hash_gen_lack_id, // lack identifier or string when generating a hash @@ -273,11 +275,19 @@ void print_parse_error(int error_type,int line,int error_token_type=__stack_end) break; case call_hash_lack_id: std::cout<push_token(); break; } this->get_token(); // check if there is a '(' or '[' or '{' after id @@ -971,53 +972,59 @@ abstract_syntax_tree nasal_parse::scalar_generate() call_vector_node.set_node_line(this_token.line); call_vector_node.set_node_type(__call_vector); // there are many kinds of ways to call a vector - // such as: id[0] id[0:12] id[-2:0] id[2:] id[4,3,1,5,2] - abstract_syntax_tree tmp=calculation(); - this->get_token(); - if(this_token.type==__colon) + // such as: id[0] id[0:12] id[-2:0] id[2:] id[4,3,1,5,2] id[0,2,4:6] + while(this_token.type!=__right_bracket) { - abstract_syntax_tree subvec_node; - + abstract_syntax_tree tmp=calculation(); this->get_token(); - subvec_node.set_node_line(this_token.line); - subvec_node.set_node_type(__sub_vector); - subvec_node.add_children(tmp); - if(this_token.type!=__right_bracket) + if(this_token.type==__colon) { - this->push_token(); - subvec_node.add_children(calculation()); - } - else - this->push_token(); - call_vector_node.add_children(subvec_node); - } - else if(this_token.type==__comma) - { - call_vector_node.add_children(tmp); - while(this_token.type!=__right_bracket) - { - call_vector_node.add_children(calculation()); + abstract_syntax_tree subvec_node; + subvec_node.set_node_line(this_token.line); + subvec_node.set_node_type(__sub_vector); + subvec_node.add_children(tmp); this->get_token(); if((this_token.type!=__comma) && (this_token.type!=__right_bracket)) + { + this->push_token(); + subvec_node.add_children(calculation()); + } + else + this->push_token(); + call_vector_node.add_children(subvec_node); + } + else if(this_token.type==__comma) + { + call_vector_node.add_children(tmp); + this->get_token(); + if(this_token.type==__right_bracket) { ++error; - print_parse_error(call_vector_lack_bracket,this_token.line,this_token.type); + print_parse_error(call_vector_wrong_comma,this_token.line,this_token.type); break; } + else + this->push_token(); + this->push_token();// push comma + } + else if(this_token.type==__right_bracket) + { + call_vector_node.add_children(tmp); + this->push_token();// push ']' + } + else + { + ++error; + print_parse_error(call_vector_wrong_token,this_token.line,this_token.type); + break; + } + this->get_token(); + if((this_token.type!=__comma) && (this_token.type!=__right_bracket)) + { + ++error; + print_parse_error(call_vector_lack_bracket,this_token.line,this_token.type); + break; } - this->push_token(); - } - else if(this_token.type==__right_bracket) - { - this->push_token(); - call_vector_node.add_children(tmp); - } - this->get_token(); - if(this_token.type!=__right_bracket) - { - ++error; - print_parse_error(call_vector_lack_bracket,this_token.line,this_token.type); - break; } scalar_node.add_children(call_vector_node); }