Nasal-Interpreter/nasal.h

194 lines
4.4 KiB
C
Raw Normal View History

2020-10-23 14:53:04 +08:00
#ifndef __NASAL_H__
#define __NASAL_H__
2020-12-14 23:43:00 +08:00
#define __nasver "9.0"
#include <stdint.h>
2020-10-23 14:53:04 +08:00
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <fstream>
2020-12-14 23:43:00 +08:00
#include <sstream>
2020-10-23 14:53:04 +08:00
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <ctime>
#include <cmath>
#include <list>
#include <stack>
#include <queue>
#include <vector>
2021-03-01 15:54:58 +08:00
#include <unordered_map>
2020-10-23 14:53:04 +08:00
2021-10-27 23:05:25 +08:00
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>
2021-10-27 23:05:25 +08:00
#ifdef _WIN32
#include <windows.h>
#else
#include <dlfcn.h>
2022-03-16 18:44:38 +08:00
#include <sys/wait.h>
#endif
2022-05-09 18:42:40 +08:00
#ifdef __linux__
#define PRTHEX64 "%lx"
#define PRTHEX64_8 "%.8lx"
#define PRTINT64 "%ld"
#else
#define PRTHEX64 "%llx"
#define PRTHEX64_8 "%.8llx"
#define PRTINT64 "%lld"
#endif
2021-06-05 20:42:58 +08:00
inline double hex_to_double(const char* str)
2020-12-14 23:43:00 +08:00
{
2021-08-09 21:30:18 +08:00
double ret=0;
for(;*str;++str)
{
ret*=16;
if('0'<=*str && *str<='9')
ret+=(*str-'0');
else if('a'<=*str && *str<='f')
ret+=(*str-'a'+10);
else if('A'<=*str && *str<='F')
ret+=(*str-'A'+10);
else
return nan("");
}
return ret;
2020-12-14 23:43:00 +08:00
}
2021-06-05 20:42:58 +08:00
inline double oct_to_double(const char* str)
2020-12-14 23:43:00 +08:00
{
2021-08-09 21:30:18 +08:00
double ret=0;
for(;*str;++str)
{
ret*=8;
if('0'<=*str && *str<'8')
ret+=(*str-'0');
else
return nan("");
}
return ret;
2020-12-14 23:43:00 +08:00
}
2021-06-05 20:42:58 +08:00
inline double dec_to_double(const char* str)
2020-12-14 23:43:00 +08:00
{
2021-08-09 21:30:18 +08:00
double ret=0,negative=1,num_pow=0;
while('0'<=*str && *str<='9')
ret=ret*10+(*str++-'0');
if(!*str) return ret;
if(*str=='.')
{
if(!*++str) return nan("");
num_pow=0.1;
while('0'<=*str && *str<='9')
{
ret+=num_pow*(*str++-'0');
num_pow*=0.1;
}
if(!*str) return ret;
}
if(*str!='e' && *str!='E')
return nan("");
if(!*++str) return nan("");
if(*str=='-' || *str=='+')
negative=(*str++=='-'? -1:1);
if(!*str) return nan("");
num_pow=0;
for(;*str;++str)
{
if('0'<=*str && *str<='9')
num_pow=num_pow*10+(*str-'0');
else
return nan("");
}
return ret*std::pow(10,negative*num_pow);
2020-12-14 23:43:00 +08:00
}
2021-06-05 20:42:58 +08:00
double str2num(const char* str)
2020-12-14 23:43:00 +08:00
{
2021-08-09 21:30:18 +08:00
bool is_negative=false;
double ret_num=0;
if(*str=='-' || *str=='+')
is_negative=(*str++=='-');
if(!*str)
return nan("");
if(str[0]=='0' && str[1]=='x')
ret_num=hex_to_double(str+2);
else if(str[0]=='0' && str[1]=='o')
ret_num=oct_to_double(str+2);
else
ret_num=dec_to_double(str);
return is_negative?-ret_num:ret_num;
2020-12-14 23:43:00 +08:00
}
int utf8_hdchk(char head)
{
// RFC-2279 but in fact now we use RFC-3629 so nbytes is less than 4
uint8_t c=(uint8_t)head;
uint32_t nbytes=0;
if((c>>5)==0x06) // 110x xxxx (10xx xxxx)^1
nbytes=1;
if((c>>4)==0x0e) // 1110 xxxx (10xx xxxx)^2
nbytes=2;
if((c>>3)==0x1e) // 1111 0xxx (10xx xxxx)^3
nbytes=3;
// these should not be true
if((c>>2)==0x3e) // 1111 10xx (10xx xxxx)^4
nbytes=4;
if((c>>1)==0x7e) // 1111 110x (10xx xxxx)^5
nbytes=5;
if(c==0xfe) // 1111 1110 (10xx xxxx)^6
nbytes=6;
return nbytes;
}
2021-10-27 23:05:25 +08:00
std::string rawstr(const std::string& str)
2021-07-21 00:20:25 +08:00
{
2021-10-14 23:22:28 +08:00
std::string ret("");
2021-08-09 21:30:18 +08:00
for(auto i:str)
{
#ifdef _WIN32
// windows ps or cmd doesn't output unicode normally
// if 'chcp65001' is not enabled, so we output the hex
if(i<=0)
{
ret+="\\x";
ret+="0123456789abcdef"[(i>>4)&15];
ret+="0123456789abcdef"[i&15];
continue;
}
#endif
2021-08-09 21:30:18 +08:00
switch(i)
{
case '\0': ret+="\\0"; break;
case '\a': ret+="\\a"; break;
case '\b': ret+="\\b"; break;
case '\e': ret+="\\e"; break;
case '\t': ret+="\\t"; break;
case '\n': ret+="\\n"; break;
case '\v': ret+="\\v"; break;
case '\f': ret+="\\f"; break;
case '\r': ret+="\\r"; break;
case '\\': ret+="\\\\";break;
case '\'': ret+="\\\'";break;
case '\"': ret+="\\\"";break;
default: ret+=i; break;
2021-08-09 21:30:18 +08:00
}
}
2021-10-14 23:22:28 +08:00
return ret;
2021-07-21 00:20:25 +08:00
}
#include "nasal_err.h"
2020-10-23 14:53:04 +08:00
#include "nasal_lexer.h"
#include "nasal_ast.h"
#include "nasal_parse.h"
#include "nasal_import.h"
#include "nasal_opt.h"
2020-10-23 14:53:04 +08:00
#include "nasal_gc.h"
#include "nasal_builtin.h"
2020-12-06 21:07:40 +08:00
#include "nasal_codegen.h"
2021-02-10 00:12:22 +08:00
#include "nasal_vm.h"
#include "nasal_dbg.h"
2020-10-23 14:53:04 +08:00
#endif