the beginning of a new interpreter
This commit is contained in:
parent
24bfbd8f0e
commit
5bba655088
|
@ -0,0 +1,172 @@
|
||||||
|
# nasal lib base.nas
|
||||||
|
# 2020/2/4
|
||||||
|
# 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
|
||||||
|
# and this ast will be linked before main ast as main-ast's beginning
|
||||||
|
|
||||||
|
# append
|
||||||
|
# The first argument specifies a vector.
|
||||||
|
# Appends the remaining arguments to the end of the vector.
|
||||||
|
var append=func(vector,elements...)
|
||||||
|
{
|
||||||
|
nasal_call_builtin_push_back(vector,elements);
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
# setsize
|
||||||
|
# Sets the size of a vector.
|
||||||
|
# The first argument specifies a vector, the second a number representing the desired size of that vector.
|
||||||
|
# If the vector is currently larger than the specified size,it is truncated.
|
||||||
|
# If it is smaller, it is padded with nil entries.Returns the vector operated upon.
|
||||||
|
var setsize=func(vector,__size)
|
||||||
|
{
|
||||||
|
nasal_call_builtin_set_size(vector,__size);
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
# subvec
|
||||||
|
# Returns a sub-range of a vector.
|
||||||
|
# The first argument specifies a vector, the second a starting index,
|
||||||
|
# and the optional third argument indicates a length (the default is to the end of the vector).
|
||||||
|
var subvec=func(vector,start,length=nil)
|
||||||
|
{
|
||||||
|
return nasal_call_builtin_subvec(vector,start,length);
|
||||||
|
}
|
||||||
|
|
||||||
|
# contains
|
||||||
|
# The first argument specifies a hash, the second must be a scalar.
|
||||||
|
# Returns 1 if the hash contains the scalar as a key, 0 if not.
|
||||||
|
var contains=func(hash,key)
|
||||||
|
{
|
||||||
|
return nasal_call_builtin_contains(hash,key);
|
||||||
|
}
|
||||||
|
|
||||||
|
# delete
|
||||||
|
# The first argument specifies a hash, the second must be a scalar key.
|
||||||
|
# Deletes the key from the hash if it exists.
|
||||||
|
# Operationally, this is identical to setting the hash value specified by the key to nil,
|
||||||
|
# but this variant potentially frees storage by deleting the reference to the key and by shrinking the hash.
|
||||||
|
var delete=func(hash,key)
|
||||||
|
{
|
||||||
|
nasal_call_builtin_delete(hash,key);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
# int
|
||||||
|
# Returns the integer part of the numeric value of the single argument, or nil if none exists.
|
||||||
|
# Truncates towards zero, not negative infinity (i.e. it's implemented in C as a double tointeger typecast).
|
||||||
|
var int=func(value)
|
||||||
|
{
|
||||||
|
return nasal_call_builtin_trans_int(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
# num
|
||||||
|
# Returns the numeric value of the single argument, or nil if none exists.
|
||||||
|
var num=func(value)
|
||||||
|
{
|
||||||
|
return nasal_call_builtin_trans_num(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
# keys
|
||||||
|
# Returns a vector containing the list of keys found in the single hash argument.
|
||||||
|
var keys=func(hash)
|
||||||
|
{
|
||||||
|
return nasal_call_builtin_get_keys(hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
# pop
|
||||||
|
# Removes and returns the last element of the single vector argument.
|
||||||
|
var pop=func(vector)
|
||||||
|
{
|
||||||
|
return nasal_call_builtin_pop_back(vector);
|
||||||
|
}
|
||||||
|
|
||||||
|
# size
|
||||||
|
# Returns the size of the single argument.
|
||||||
|
# For strings, this is the length in bytes.
|
||||||
|
# For vectors, this is the number of elements.
|
||||||
|
# For hashes, it is the number of key/value pairs.
|
||||||
|
# Returns nil for number and nil arguments.
|
||||||
|
var size=func(object)
|
||||||
|
{
|
||||||
|
return nasal_call_builtin_sizeof(object);
|
||||||
|
}
|
||||||
|
|
||||||
|
# streq
|
||||||
|
# Tests the string values of the two arguments for equality.
|
||||||
|
# Needed because the == operator in Nasal tests for numeric equality, as in perl.
|
||||||
|
# So "0" == "0.0" is true,but streq("0", "0.0") is false.
|
||||||
|
# This is rarely required in typical code.
|
||||||
|
var streq=func(__a,__b)
|
||||||
|
{
|
||||||
|
return nasal_call_builtin_str_cmp_equal(__a,__b);
|
||||||
|
}
|
||||||
|
|
||||||
|
# cmp
|
||||||
|
# Compares two strings, returning -1 if a is less than b, 0 if theyare identical, and 1 if a is greater than b.
|
||||||
|
var cmp=func(__a,__b)
|
||||||
|
{
|
||||||
|
return nasal_call_builtin_cmp(__a,__b);
|
||||||
|
}
|
||||||
|
|
||||||
|
# sort
|
||||||
|
# Creates a new vector containing the elements in the input vector sorted in ascending order according to the rule givenby function,
|
||||||
|
# which takes two arguments (elements of the input vector) and should return less than zero, zero, or greater than zero if the first argument is,
|
||||||
|
# respectively, less than, equal to, or greater than the second argument. Despite being implemented with ANSI C qsort(),
|
||||||
|
# the sort is stable; "equal" elements in the output vector will appear in the same relative order as they do in the input.
|
||||||
|
var sort=func(vector,function)
|
||||||
|
{
|
||||||
|
nasal_call_builtin_cpp_sort(vector,function);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
# substr
|
||||||
|
# Computes a substring.
|
||||||
|
# The first argument specifes a string, the second is an integer index of the start of a substring,
|
||||||
|
# the optional third argument specifies a length (the default is to return the remaining string).
|
||||||
|
# Example: substr("abcde", 1, 3) returns "bcd".
|
||||||
|
var substr=func(__string,start,length=nil)
|
||||||
|
{
|
||||||
|
return nasal_call_builtin_substr(__string,start,length);
|
||||||
|
}
|
||||||
|
|
||||||
|
# sprintf
|
||||||
|
# Creates and returns a string formatted as per ANSI C sprintf().
|
||||||
|
var sprintf=func(__format,var_args...)
|
||||||
|
{
|
||||||
|
return nasal_call_builtin_sprintf(__format,var_args);
|
||||||
|
}
|
||||||
|
|
||||||
|
# find
|
||||||
|
# Finds and returns the index of the first occurence of the string needle in the string haystack, or -1 if no such occurence was found.
|
||||||
|
var find=func(needle,haystack)
|
||||||
|
{
|
||||||
|
return nasal_call_builtin_find_first_occur(needle,haystack);
|
||||||
|
}
|
||||||
|
|
||||||
|
# split
|
||||||
|
# Splits the input string into a vector of substrings bounded by occurences of the delimeter substring.
|
||||||
|
var split=func(delimeter,__string)
|
||||||
|
{
|
||||||
|
return nasal_call_builtin_split(delimeter,__string);
|
||||||
|
}
|
||||||
|
|
||||||
|
# rand
|
||||||
|
# Returns a random number in the range [0:1) (that is, 0.0 is a possible return value. 1.0 is not).
|
||||||
|
# If a numeric argument is specified, it is used as a seed instead and the function returns nil.
|
||||||
|
# Implemented in terms of the C library's rand/srand functions;
|
||||||
|
# the result should have a full double-precision number's worth of randomness even on systems with a 15 bit rand().
|
||||||
|
var rand=func(seed=nil)
|
||||||
|
{
|
||||||
|
return nasal_call_builtin_rand(seed);
|
||||||
|
}
|
||||||
|
|
||||||
|
# id
|
||||||
|
# Returns a unique string identifying the object.
|
||||||
|
# Two id strings are equal if and only if the two references point to the same object in memory.
|
||||||
|
# Numbers don't have id's and will cause a runtime error if passed to id().
|
||||||
|
var id=func(thing)
|
||||||
|
{
|
||||||
|
return nasal_call_builtin_get_id(thing);
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
# nasal lib bits.nas
|
||||||
|
# 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
|
||||||
|
# and this ast will be linked before main ast as main-ast's beginning
|
||||||
|
|
||||||
|
var bits=
|
||||||
|
{
|
||||||
|
# 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)
|
||||||
|
{
|
||||||
|
return nasal_call_builtin_bitcalc(__string,startbit,length);
|
||||||
|
},
|
||||||
|
# As bits.fld(), but interprets the result as a 2's complement signed value.
|
||||||
|
sfld:func(__string,startbit,length)
|
||||||
|
{
|
||||||
|
return nasal_call_builtin_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)
|
||||||
|
{
|
||||||
|
return nasal_call_builtin_setbit(__string,startbit,length,value);
|
||||||
|
},
|
||||||
|
# Returns a zero-filled mutable string of the specified length.
|
||||||
|
buf:func(length)
|
||||||
|
{
|
||||||
|
return nasal_call_builtin_null_string_gen(length);
|
||||||
|
},
|
||||||
|
};
|
|
@ -0,0 +1,74 @@
|
||||||
|
# nasal lib io.nas
|
||||||
|
# 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
|
||||||
|
# and this ast will be linked before main ast as main-ast's beginning
|
||||||
|
|
||||||
|
var io=
|
||||||
|
{
|
||||||
|
# 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")
|
||||||
|
{
|
||||||
|
return nasal_call_builtin_c_fopen(filename,mode);
|
||||||
|
},
|
||||||
|
# Closes the specified file as per ANSI fclose().
|
||||||
|
close:func(filehandle)
|
||||||
|
{
|
||||||
|
nasal_call_builtin_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)
|
||||||
|
{
|
||||||
|
return nasal_call_builtin_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)
|
||||||
|
{
|
||||||
|
return nasal_call_builtin_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)
|
||||||
|
{
|
||||||
|
nasal_call_builtin_c_seek(filehandle,position,whence);
|
||||||
|
return;
|
||||||
|
},
|
||||||
|
# Returns the current seek position of the filehandle.
|
||||||
|
tell:func(filehandle)
|
||||||
|
{
|
||||||
|
return nasal_call_builtin_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)
|
||||||
|
{
|
||||||
|
return nasal_call_builtin_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)
|
||||||
|
{
|
||||||
|
return nasal_call_builtin_builtin_stat(filename);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
var print=func(dyn...)
|
||||||
|
{
|
||||||
|
nasal_call_builtin_c_std_puts(dyn);
|
||||||
|
return nil;
|
||||||
|
};
|
|
@ -0,0 +1,49 @@
|
||||||
|
# nasal lib math.nas
|
||||||
|
# 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
|
||||||
|
# and this ast will be linked before main ast as main-ast's beginning
|
||||||
|
|
||||||
|
var math=
|
||||||
|
{
|
||||||
|
# Euler's constant
|
||||||
|
e:2.7182818284590452354,
|
||||||
|
pi:3.14159265358979323846,
|
||||||
|
# Returns the sine of the single argument
|
||||||
|
sin:func(x)
|
||||||
|
{
|
||||||
|
return nasal_call_builtin_sin(x);
|
||||||
|
},
|
||||||
|
# Returns the cosine of the single argument
|
||||||
|
cos:func(x)
|
||||||
|
{
|
||||||
|
return nasal_call_builtin_cos(x);
|
||||||
|
},
|
||||||
|
# you know what the f*ck this is
|
||||||
|
tan:func(x)
|
||||||
|
{
|
||||||
|
return nasal_call_builtin_tan(x);
|
||||||
|
},
|
||||||
|
# Returns e (Euler's constant) raised to the power specified by the single argument
|
||||||
|
exp:func(x)
|
||||||
|
{
|
||||||
|
return nasal_call_builtin_exp(x);
|
||||||
|
},
|
||||||
|
# Returns the natural logarithm of the single argument.
|
||||||
|
ln:func(x)
|
||||||
|
{
|
||||||
|
return nasal_call_builtin_cpp_math_ln(x);
|
||||||
|
},
|
||||||
|
# Returns the square root of the single argument.
|
||||||
|
sqrt:func(x)
|
||||||
|
{
|
||||||
|
return nasal_call_builtin_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)
|
||||||
|
{
|
||||||
|
return nasal_call_builtin_cpp_atan2(x,y);
|
||||||
|
},
|
||||||
|
};
|
|
@ -0,0 +1,12 @@
|
||||||
|
# nasal lib readline.nas
|
||||||
|
# 2020/2/6
|
||||||
|
# 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
|
||||||
|
# and this ast will be linked before main ast as main-ast's beginning
|
||||||
|
|
||||||
|
# GNU Readline Library
|
||||||
|
var readline=func(prompt="> ")
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
# nasal lib regex.nas
|
||||||
|
# 2020/2/6
|
||||||
|
# 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
|
||||||
|
# and this ast will be linked before main ast as main-ast's beginning
|
||||||
|
|
||||||
|
var regex=
|
||||||
|
{
|
||||||
|
comp:func(){},
|
||||||
|
exec:func(){},
|
||||||
|
};
|
|
@ -0,0 +1,15 @@
|
||||||
|
# nasal lib sqlite.nas
|
||||||
|
# 2020/2/6
|
||||||
|
# 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
|
||||||
|
# and this ast will be linked before main ast as main-ast's beginning
|
||||||
|
|
||||||
|
var sqlite=
|
||||||
|
{
|
||||||
|
open:func(){},
|
||||||
|
close:func(){},
|
||||||
|
prepare:func(){},
|
||||||
|
exec:func(){},
|
||||||
|
finalize:func(){},
|
||||||
|
};
|
|
@ -0,0 +1,9 @@
|
||||||
|
var system=
|
||||||
|
{
|
||||||
|
# print the type of thing on the screen
|
||||||
|
type:func(thing)
|
||||||
|
{
|
||||||
|
nasal_call_builtin_scalar_type(thing);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,17 @@
|
||||||
|
# nasal lib thread.nas
|
||||||
|
# 2020/2/6
|
||||||
|
# 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
|
||||||
|
# and this ast will be linked before main ast as main-ast's beginning
|
||||||
|
|
||||||
|
var thread=
|
||||||
|
{
|
||||||
|
newthread:func(){},
|
||||||
|
newlock:func(){},
|
||||||
|
lock:func(){},
|
||||||
|
unlock:func(){},
|
||||||
|
newsem:func(){},
|
||||||
|
semdown:func(){},
|
||||||
|
semup:func(){},
|
||||||
|
};
|
|
@ -0,0 +1,22 @@
|
||||||
|
# nasal lib unix.nas
|
||||||
|
# 2020/2/6
|
||||||
|
# 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
|
||||||
|
# and this ast will be linked before main ast as main-ast's beginning
|
||||||
|
|
||||||
|
var unix=
|
||||||
|
{
|
||||||
|
pipe:func(){},
|
||||||
|
fork:func(){},
|
||||||
|
dup2:func(){},
|
||||||
|
exec:func(){},
|
||||||
|
waitpid:func(){},
|
||||||
|
opendir:func(){},
|
||||||
|
readdir:func(){},
|
||||||
|
closedir:func(){},
|
||||||
|
time:func(){},
|
||||||
|
chdir:func(){},
|
||||||
|
environ:func(){},
|
||||||
|
sleep:func(){},
|
||||||
|
};
|
|
@ -0,0 +1,15 @@
|
||||||
|
# nasal lib utf8.nas
|
||||||
|
# 2020/2/6
|
||||||
|
# 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
|
||||||
|
# and this ast will be linked before main ast as main-ast's beginning
|
||||||
|
|
||||||
|
var utf8=
|
||||||
|
{
|
||||||
|
chstr:func(){},
|
||||||
|
strc:func(){},
|
||||||
|
substr:func(){},
|
||||||
|
size:func(){},
|
||||||
|
validate:func(){},
|
||||||
|
};
|
|
@ -0,0 +1,99 @@
|
||||||
|
#include "nasal.h"
|
||||||
|
|
||||||
|
void logo()
|
||||||
|
{
|
||||||
|
std::cout<<" __ _ "<<std::endl;
|
||||||
|
std::cout<<" /\\ \\ \\__ _ ___ __ _| | "<<std::endl;
|
||||||
|
std::cout<<" / \\/ / _` / __|/ _` | | "<<std::endl;
|
||||||
|
std::cout<<" / /\\ / (_| \\__ \\ (_| | | "<<std::endl;
|
||||||
|
std::cout<<" \\_\\ \\/ \\__,_|___/\\__,_|_|"<<std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nasal_resource resource;
|
||||||
|
std::string command;
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
// use chcp 65001 to use unicode io
|
||||||
|
system("chcp 65001");
|
||||||
|
#endif
|
||||||
|
// this curve looks really cool
|
||||||
|
logo();
|
||||||
|
#ifdef _WIN32
|
||||||
|
std::cout<<">> [system] Windows system."<<std::endl;
|
||||||
|
#endif
|
||||||
|
#ifdef _linux_
|
||||||
|
std::cout<<">> [system] Linux system."<<std::endl;
|
||||||
|
#endif
|
||||||
|
#ifdef TARGET_OS_MAC
|
||||||
|
std::cout<<">> [system] MacOS system."<<std::endl;
|
||||||
|
#endif
|
||||||
|
std::cout<<">> Nasal interpreter ver 3.0 ."<<std::endl;
|
||||||
|
std::cout<<">> Code: https://github.com/ValKmjolnir/Nasal-Interpreter"<<std::endl;
|
||||||
|
std::cout<<">> More info: http://wiki.flightgear.org/Nasal_scripting_language"<<std::endl;
|
||||||
|
std::cout<<">> Input \"help\" to get help ."<<std::endl;
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
std::cout<<">> ";
|
||||||
|
std::cin>>command;
|
||||||
|
if(command=="help")
|
||||||
|
{
|
||||||
|
std::cout<<">> [\'file\'] input a file."<<std::endl;
|
||||||
|
std::cout<<">> [cls ] clear the screen."<<std::endl;
|
||||||
|
std::cout<<">> [del ] clear the resource code."<<std::endl;
|
||||||
|
std::cout<<">> [lib ] add lib file."<<std::endl;
|
||||||
|
std::cout<<">> [rs ] print resource code."<<std::endl;
|
||||||
|
std::cout<<">> [lex ] turn code into tokens."<<std::endl;
|
||||||
|
std::cout<<">> [par ] turn tokens into abstract syntax tree."<<std::endl;
|
||||||
|
std::cout<<">> [ast ] check the abstract syntax tree."<<std::endl;
|
||||||
|
std::cout<<">> [run ] run code."<<std::endl;
|
||||||
|
std::cout<<">> [logo ] print logo of nasal ."<<std::endl;
|
||||||
|
std::cout<<">> [exit ] quit nasal interpreter."<<std::endl;
|
||||||
|
}
|
||||||
|
else if(command=="cls")
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
system("cls");
|
||||||
|
#endif
|
||||||
|
#ifdef _linux_
|
||||||
|
system("clear");
|
||||||
|
#endif
|
||||||
|
#ifdef TARGET_OS_MAC
|
||||||
|
system("clear");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else if(command=="del")
|
||||||
|
{
|
||||||
|
resource.delete_file();
|
||||||
|
std::cout<<">> [Delete] complete."<<std::endl;
|
||||||
|
}
|
||||||
|
else if(command=="lib")
|
||||||
|
resource.load_lib();
|
||||||
|
else if(command=="rs")
|
||||||
|
resource.print_file();
|
||||||
|
else if(command=="lex")
|
||||||
|
{
|
||||||
|
;
|
||||||
|
}
|
||||||
|
else if(command=="par")
|
||||||
|
{
|
||||||
|
;
|
||||||
|
}
|
||||||
|
else if(command=="ast")
|
||||||
|
{
|
||||||
|
;
|
||||||
|
}
|
||||||
|
else if(command=="run")
|
||||||
|
{
|
||||||
|
;
|
||||||
|
}
|
||||||
|
else if(command=="logo")
|
||||||
|
logo();
|
||||||
|
else if(command=="exit")
|
||||||
|
break;
|
||||||
|
else
|
||||||
|
resource.input_file(command);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
#ifndef __NASAL_H__
|
||||||
|
#define __NASAL_H__
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
#include <cstring>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <ctime>
|
||||||
|
#include <cmath>
|
||||||
|
/* if thread is used, don't forget to add -std=c++11 or higher standard before executing */
|
||||||
|
// #include <thread>
|
||||||
|
#include <list>
|
||||||
|
#include <stack>
|
||||||
|
#include <queue>
|
||||||
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
#include "nasal_enum.h"
|
||||||
|
#include "nasal_resource.h"
|
||||||
|
#include "nasal_lexer.h"
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,21 @@
|
||||||
|
#ifndef __NASAL_ENUM_H__
|
||||||
|
#define __NASAL_ENUM_H__
|
||||||
|
|
||||||
|
/* token_type is used in lexer */
|
||||||
|
enum token_type
|
||||||
|
{
|
||||||
|
tok_null=0,
|
||||||
|
tok_number,tok_string,
|
||||||
|
tok_for,tok_forindex,tok_foreach,tok_while,
|
||||||
|
tok_var,tok_func,tok_break,tok_continue,
|
||||||
|
tok_return,tok_if,tok_elsif,tok_else,tok_nil,
|
||||||
|
tok_left_curve,tok_right_curve,
|
||||||
|
tok_left_bracket,tok_right_bracket,
|
||||||
|
tok_left_brace,tok_right_brace,
|
||||||
|
tok_semi,tok_and,tok_or,tok_comma,tok_dot,tok_ellipsis,tok_quesmark,
|
||||||
|
tok_colon,tok_add,tok_sub,tok_mult,tok_div,tok_link,tok_not,
|
||||||
|
tok_add_equal,tok_sub_equal,tok_mult_equal,tok_div_equal,tok_link_equal,
|
||||||
|
tok_cmp_equal,tok_cmp_not_equal,tok_less_than,tok_greater_than,tok_less_equal,tok_greater_equal
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,99 @@
|
||||||
|
#ifndef __NASAL_LEXER_H__
|
||||||
|
#define __NASAL_LEXER_H__
|
||||||
|
|
||||||
|
#define IS_IDENTIFIER_HEAD(c) (c=='_')||('a'<=c && c<='z')||('A'<=c&&c<='Z')
|
||||||
|
#define IS_IDENTIFIER_BODY(c) (c=='_')||('a'<=c && c<='z')||('A'<=c&&c<='Z')||('0'<=c&&c<='9')
|
||||||
|
#define IS_NUMBER_HEAD(c) ('0'<=c&&c<='9')
|
||||||
|
#define IS_NUMBER_BODY(c) ('0'<=c&&c<='9')||('a'<=c&&c<='f')||('A'<=c&&c<='F')||(c=='e'||c=='E'||c=='.'||c=='x'||c=='o')
|
||||||
|
#define IS_STRING_HEAD(c) (c=='\''||c=='\"')
|
||||||
|
// single operators have only one character
|
||||||
|
#define IS_SINGLE_OPRATOR(c) (c=='('||c==')'||c=='['||c==']'||c=='{'||c=='}'||c==','||c==';'||c=='|'||c==':'||\
|
||||||
|
c=='?'||c=='`'||c=='&'||c=='@'||c=='%'||c=='$'||c=='^'||c=='\\')
|
||||||
|
#define IS_DOT(c) (c=='.')
|
||||||
|
// calculation operators may have two chars, for example: += -= *= /= ~= != == >= <=
|
||||||
|
#define IS_CALC_OPERATOR(c) (c=='='||c=='+'||c=='-'||c=='*'||c=='!'||c=='/'||c=='<'||c=='>'||c=='~')
|
||||||
|
#define IS_NOTE_HEAD(c) (c=='#')
|
||||||
|
|
||||||
|
#ifndef TOKEN_TABLE_SIZE
|
||||||
|
#define TOKEN_TABLE_SIZE 44
|
||||||
|
struct token_table
|
||||||
|
{
|
||||||
|
std::string str;
|
||||||
|
int tok_type;
|
||||||
|
}tok_tbl[TOKEN_TABLE_SIZE]=
|
||||||
|
{
|
||||||
|
{"for" ,tok_for },
|
||||||
|
{"forindex",tok_forindex },
|
||||||
|
{"foreach" ,tok_foreach },
|
||||||
|
{"while" ,tok_while },
|
||||||
|
{"var" ,tok_var },
|
||||||
|
{"func" ,tok_func },
|
||||||
|
{"break" ,tok_break },
|
||||||
|
{"continue",tok_continue },
|
||||||
|
{"return" ,tok_return },
|
||||||
|
{"if" ,tok_if },
|
||||||
|
{"elsif" ,tok_elsif },
|
||||||
|
{"else" ,tok_else },
|
||||||
|
{"nil" ,tok_nil },
|
||||||
|
{"(" ,tok_left_curve },
|
||||||
|
{")" ,tok_right_curve },
|
||||||
|
{"[" ,tok_left_bracket },
|
||||||
|
{"]" ,tok_right_bracket},
|
||||||
|
{"{" ,tok_left_brace },
|
||||||
|
{"}" ,tok_right_brace },
|
||||||
|
{";" ,tok_semi },
|
||||||
|
{"and" ,tok_and },
|
||||||
|
{"or" ,tok_or },
|
||||||
|
{"," ,tok_comma },
|
||||||
|
{"." ,tok_dot },
|
||||||
|
{"..." ,tok_ellipsis },
|
||||||
|
{"?" ,tok_quesmark },
|
||||||
|
{":" ,tok_colon },
|
||||||
|
{"+" ,tok_add },
|
||||||
|
{"-" ,tok_sub },
|
||||||
|
{"*" ,tok_mult },
|
||||||
|
{"/" ,tok_div },
|
||||||
|
{"~" ,tok_link },
|
||||||
|
{"!" ,tok_not },
|
||||||
|
{"+=" ,tok_add_equal },
|
||||||
|
{"-=" ,tok_sub_equal },
|
||||||
|
{"*=" ,tok_mult_equal },
|
||||||
|
{"/=" ,tok_div_equal },
|
||||||
|
{"~=" ,tok_link_equal },
|
||||||
|
{"==" ,tok_cmp_equal },
|
||||||
|
{"!=" ,tok_cmp_not_equal},
|
||||||
|
{"<" ,tok_less_than },
|
||||||
|
{">" ,tok_greater_than },
|
||||||
|
{"<=" ,tok_less_equal },
|
||||||
|
{">=" ,tok_greater_equal},
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct token
|
||||||
|
{
|
||||||
|
int line;
|
||||||
|
int type;
|
||||||
|
std::string str;
|
||||||
|
};
|
||||||
|
|
||||||
|
class nasal_lexer
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
std::vector<token> token_list;
|
||||||
|
public:
|
||||||
|
void delete_tokens();
|
||||||
|
void scanner(std::vector<char>&);
|
||||||
|
};
|
||||||
|
|
||||||
|
void nasal_lexer::delete_tokens()
|
||||||
|
{
|
||||||
|
token_list.clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nasal_lexer::scanner(std::vector<char>& res)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,97 @@
|
||||||
|
#ifndef __NASAL_RESOURCE_H__
|
||||||
|
#define __NASAL_RESOURCE_H__
|
||||||
|
|
||||||
|
/* filenames of lib files */
|
||||||
|
#ifndef LIB_FILE_NUM
|
||||||
|
#define LIB_FILE_NUM 11
|
||||||
|
const std::string lib_filename[LIB_FILE_NUM]=
|
||||||
|
{
|
||||||
|
"lib/base.nas",
|
||||||
|
"lib/bits.nas",
|
||||||
|
"lib/io.nas",
|
||||||
|
"lib/math.nas",
|
||||||
|
"lib/readline.nas",
|
||||||
|
"lib/regex.nas",
|
||||||
|
"lib/sqlite.nas",
|
||||||
|
"lib/system.nas",
|
||||||
|
"lib/thread.nas",
|
||||||
|
"lib/unix.nas",
|
||||||
|
"lib/utf8.nas"
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class nasal_resource
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
std::vector<char> res;
|
||||||
|
public:
|
||||||
|
void input_file(std::string);
|
||||||
|
void load_lib();
|
||||||
|
void delete_file();
|
||||||
|
void print_file();
|
||||||
|
std::vector<char>& get_file();
|
||||||
|
};
|
||||||
|
|
||||||
|
void nasal_resource::input_file(std::string filename)
|
||||||
|
{
|
||||||
|
std::ifstream fin(filename,std::ios::binary);
|
||||||
|
if(fin.fail())
|
||||||
|
{
|
||||||
|
std::cout<<">> [resource] cannot open file \'"<<filename<<"\'."<<std::endl;
|
||||||
|
fin.close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
while(!fin.eof())
|
||||||
|
{
|
||||||
|
char c=fin.get();
|
||||||
|
if(fin.eof()) break;
|
||||||
|
res.push_back(c);
|
||||||
|
}
|
||||||
|
fin.close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nasal_resource::load_lib()
|
||||||
|
{
|
||||||
|
for(int i=0;i<LIB_FILE_NUM;++i)
|
||||||
|
this->input_file(lib_filename[i]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nasal_resource::delete_file()
|
||||||
|
{
|
||||||
|
res.clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nasal_resource::print_file()
|
||||||
|
{
|
||||||
|
int size=res.size(),line=1;
|
||||||
|
std::cout<<line<<"\t";
|
||||||
|
std::string unicode_str="";
|
||||||
|
for(int i=0;i<size;++i)
|
||||||
|
{
|
||||||
|
if(res[i]>=0 && unicode_str.length())
|
||||||
|
{
|
||||||
|
std::cout<<unicode_str;
|
||||||
|
unicode_str="";
|
||||||
|
}
|
||||||
|
if(32<=res[i]) std::cout<<res[i];
|
||||||
|
else if(res[i]<0) unicode_str+=res[i];
|
||||||
|
else std::cout<<" ";
|
||||||
|
if(res[i]=='\n')
|
||||||
|
{
|
||||||
|
++line;
|
||||||
|
std::cout<<std::endl<<line<<"\t";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::cout<<(unicode_str.length()?unicode_str:"")<<std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<char>& nasal_resource::get_file()
|
||||||
|
{
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue