✨ change ast used in parser
This commit is contained in:
parent
0132ca0870
commit
2ce13e2134
|
@ -58,3 +58,301 @@ hash_pair::~hash_pair() {
|
|||
void hash_pair::accept(ast_visitor* visitor) {
|
||||
visitor->visit_hash_pair(this);
|
||||
}
|
||||
|
||||
function::~function() {
|
||||
for(auto i : parameter_list) {
|
||||
delete i;
|
||||
}
|
||||
if (block) {
|
||||
delete block;
|
||||
}
|
||||
}
|
||||
|
||||
void function::accept(ast_visitor* visitor) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
code_block::~code_block() {
|
||||
for(auto i : expressions) {
|
||||
delete i;
|
||||
}
|
||||
}
|
||||
|
||||
void code_block::accept(ast_visitor* visitor) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
parameter::~parameter() {
|
||||
if (name) {
|
||||
delete name;
|
||||
}
|
||||
if (default_value) {
|
||||
delete default_value;
|
||||
}
|
||||
}
|
||||
|
||||
void parameter::accept(ast_visitor* visitor) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
ternary_operator::~ternary_operator() {
|
||||
if (condition) {
|
||||
delete condition;
|
||||
}
|
||||
if (left) {
|
||||
delete left;
|
||||
}
|
||||
if (right) {
|
||||
delete right;
|
||||
}
|
||||
}
|
||||
|
||||
void ternary_operator::accept(ast_visitor* visitor) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
binary_operator::~binary_operator() {
|
||||
if (left) {
|
||||
delete left;
|
||||
}
|
||||
if (right) {
|
||||
delete right;
|
||||
}
|
||||
}
|
||||
|
||||
void binary_operator::accept(ast_visitor* visitor) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
unary_operator::~unary_operator() {
|
||||
if (value) {
|
||||
delete value;
|
||||
}
|
||||
}
|
||||
|
||||
void unary_operator::accept(ast_visitor* visitor) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
call_expr::~call_expr() {
|
||||
if(first) {
|
||||
delete first;
|
||||
}
|
||||
for(auto i : calls) {
|
||||
delete i;
|
||||
}
|
||||
}
|
||||
|
||||
void call_expr::accept(ast_visitor* visitor) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void call_hash::accept(ast_visitor* visitor) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
call_vector::~call_vector() {
|
||||
for(auto i : calls) {
|
||||
delete i;
|
||||
}
|
||||
}
|
||||
|
||||
void call_vector::accept(ast_visitor* visitor) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
call_function::~call_function() {
|
||||
for(auto i : args) {
|
||||
delete i;
|
||||
}
|
||||
}
|
||||
|
||||
void call_function::accept(ast_visitor* visitor) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
slice_vector::~slice_vector() {
|
||||
if (begin) {
|
||||
delete begin;
|
||||
}
|
||||
if (end) {
|
||||
delete end;
|
||||
}
|
||||
}
|
||||
|
||||
void slice_vector::accept(ast_visitor* visitor) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
definition_expr::~definition_expr() {
|
||||
if (variable_name) {
|
||||
delete variable_name;
|
||||
}
|
||||
if (variables) {
|
||||
delete variables;
|
||||
}
|
||||
if (value) {
|
||||
delete value;
|
||||
}
|
||||
}
|
||||
|
||||
void definition_expr::accept(ast_visitor* visitor) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
assignment_expr::~assignment_expr() {
|
||||
if (left) {
|
||||
delete left;
|
||||
}
|
||||
if (right) {
|
||||
delete right;
|
||||
}
|
||||
}
|
||||
|
||||
void assignment_expr::accept(ast_visitor* visitor) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
multi_define::~multi_define() {
|
||||
for(auto i : variables) {
|
||||
delete i;
|
||||
}
|
||||
if (value) {
|
||||
delete value;
|
||||
}
|
||||
}
|
||||
|
||||
void multi_define::accept(ast_visitor* visitor) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
tuple_expr::~tuple_expr() {
|
||||
for(auto i : elements) {
|
||||
delete i;
|
||||
}
|
||||
}
|
||||
|
||||
void tuple_expr::accept(ast_visitor* visitor) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
multi_assign::~multi_assign() {
|
||||
if (left) {
|
||||
delete left;
|
||||
}
|
||||
if (right) {
|
||||
delete right;
|
||||
}
|
||||
}
|
||||
|
||||
void multi_assign::accept(ast_visitor* visitor) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
while_expr::~while_expr() {
|
||||
if (condition) {
|
||||
delete condition;
|
||||
}
|
||||
if (block) {
|
||||
delete block;
|
||||
}
|
||||
}
|
||||
|
||||
void while_expr::accept(ast_visitor* visitor) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
for_expr::~for_expr() {
|
||||
if (initializing) {
|
||||
delete initializing;
|
||||
}
|
||||
if (condition) {
|
||||
delete condition;
|
||||
}
|
||||
if (step) {
|
||||
delete step;
|
||||
}
|
||||
if (block) {
|
||||
delete block;
|
||||
}
|
||||
}
|
||||
|
||||
void for_expr::accept(ast_visitor* visitor) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
iter_expr::~iter_expr() {
|
||||
if (name) {
|
||||
delete name;
|
||||
}
|
||||
if (call) {
|
||||
delete call;
|
||||
}
|
||||
}
|
||||
|
||||
void iter_expr::accept(ast_visitor* visitor) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
forei_expr::~forei_expr() {
|
||||
if (iterator) {
|
||||
delete iterator;
|
||||
}
|
||||
if (vector_node) {
|
||||
delete vector_node;
|
||||
}
|
||||
if (block) {
|
||||
delete block;
|
||||
}
|
||||
}
|
||||
|
||||
void forei_expr::accept(ast_visitor* visitor) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
condition_expr::~condition_expr() {
|
||||
if (if_stmt) {
|
||||
delete if_stmt;
|
||||
}
|
||||
for(auto i : elsif_stmt) {
|
||||
delete i;
|
||||
}
|
||||
if (else_stmt) {
|
||||
delete else_stmt;
|
||||
}
|
||||
}
|
||||
|
||||
void condition_expr::accept(ast_visitor* visitor) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
if_expr::~if_expr() {
|
||||
if (condition) {
|
||||
delete condition;
|
||||
}
|
||||
if (block) {
|
||||
delete block;
|
||||
}
|
||||
}
|
||||
|
||||
void if_expr::accept(ast_visitor* visitor) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void continue_expr::accept(ast_visitor* visitor) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void break_expr::accept(ast_visitor* visitor) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
return_expr::~return_expr() {
|
||||
if (value) {
|
||||
delete value;
|
||||
}
|
||||
}
|
||||
|
||||
void return_expr::accept(ast_visitor* visitor) {
|
||||
// TODO
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "nasal.h"
|
||||
#include "nasal_err.h"
|
||||
#include "nasal_new_header.h"
|
||||
#include "nasal_new_err.h"
|
||||
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
|
@ -51,6 +51,7 @@ enum class expr_type:u32 {
|
|||
ast_multi_id, // multi identifiers sub-tree
|
||||
ast_tuple,
|
||||
ast_def, // definition
|
||||
ast_assign,
|
||||
ast_multi_assign,
|
||||
ast_continue, // continue keyword, only used in loop
|
||||
ast_break, // break keyword, only used in loop
|
||||
|
@ -88,7 +89,7 @@ public:
|
|||
nd_loc.end_line = location.end_line;
|
||||
nd_loc.end_column = location.end_column;
|
||||
}
|
||||
virtual void accept(ast_visitor*);
|
||||
void accept(ast_visitor*);
|
||||
};
|
||||
|
||||
class null_expr:public expr {
|
||||
|
@ -115,6 +116,7 @@ public:
|
|||
number_literal(const span& location, const f64 num):
|
||||
expr(location, expr_type::ast_num), number(num) {}
|
||||
~number_literal() = default;
|
||||
f64 get_number() const {return number;}
|
||||
void accept(ast_visitor*) override;
|
||||
};
|
||||
|
||||
|
@ -126,6 +128,7 @@ public:
|
|||
string_literal(const span& location, const std::string& str):
|
||||
expr(location, expr_type::ast_str), content(str) {}
|
||||
~string_literal() = default;
|
||||
const std::string get_content() const {return content;}
|
||||
void accept(ast_visitor*) override;
|
||||
};
|
||||
|
||||
|
@ -137,6 +140,7 @@ public:
|
|||
identifier(const span& location, const std::string& str):
|
||||
expr(location, expr_type::ast_id), name(str) {}
|
||||
~identifier() = default;
|
||||
const std::string get_name() const {return name;}
|
||||
void accept(ast_visitor*) override;
|
||||
};
|
||||
|
||||
|
@ -346,7 +350,7 @@ public:
|
|||
call_hash(const span& location, const std::string& name):
|
||||
expr(location, expr_type::ast_callh),
|
||||
field(name) {}
|
||||
~call_hash();
|
||||
~call_hash() = default;
|
||||
void accept(ast_visitor*) override;
|
||||
};
|
||||
|
||||
|
@ -405,6 +409,42 @@ public:
|
|||
void set_identifier(identifier* node) {variable_name = node;}
|
||||
void set_multi_define(multi_define* node) {variables = node;}
|
||||
void set_value(expr* node) {value = node;}
|
||||
|
||||
expr* get_value() {return value;}
|
||||
void accept(ast_visitor*) override;
|
||||
};
|
||||
|
||||
class assignment_expr:public expr {
|
||||
public:
|
||||
enum class assign_type {
|
||||
equal,
|
||||
add_equal,
|
||||
sub_equal,
|
||||
mult_equal,
|
||||
div_equal,
|
||||
concat_equal,
|
||||
bitwise_and_equal,
|
||||
bitwise_or_equal,
|
||||
bitwise_xor_equal
|
||||
};
|
||||
|
||||
private:
|
||||
assign_type type;
|
||||
expr* left;
|
||||
expr* right;
|
||||
|
||||
public:
|
||||
assignment_expr(const span& location):
|
||||
expr(location, expr_type::ast_assign),
|
||||
left(nullptr), right(nullptr) {}
|
||||
~assignment_expr();
|
||||
void set_type(assign_type operator_type) {type = operator_type;}
|
||||
void set_left(expr* node) {left = node;}
|
||||
void set_right(expr* node) {right = node;}
|
||||
|
||||
assign_type get_type() const {return type;}
|
||||
expr* get_left() {return left;}
|
||||
expr* get_right() {return right;}
|
||||
void accept(ast_visitor*) override;
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,163 @@
|
|||
#include "nasal_new_err.h"
|
||||
|
||||
std::ostream& back_white(std::ostream& s) {
|
||||
#ifdef _WIN32
|
||||
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0xf0);
|
||||
#else
|
||||
s<<"\033[7m";
|
||||
#endif
|
||||
return s;
|
||||
}
|
||||
|
||||
std::ostream& red(std::ostream& s) {
|
||||
#ifdef _WIN32
|
||||
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0x0c);
|
||||
#else
|
||||
s<<"\033[91;1m";
|
||||
#endif
|
||||
return s;
|
||||
}
|
||||
|
||||
std::ostream& cyan(std::ostream& s) {
|
||||
#ifdef _WIN32
|
||||
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0x03);
|
||||
#else
|
||||
s<<"\033[36;1m";
|
||||
#endif
|
||||
return s;
|
||||
}
|
||||
|
||||
std::ostream& orange(std::ostream& s) {
|
||||
#ifdef _WIN32
|
||||
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0x0e);
|
||||
#else
|
||||
s<<"\033[93;1m";
|
||||
#endif
|
||||
return s;
|
||||
}
|
||||
|
||||
std::ostream& white(std::ostream& s) {
|
||||
#ifdef _WIN32
|
||||
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0x0f);
|
||||
#else
|
||||
s<<"\033[0m\033[1m";
|
||||
#endif
|
||||
return s;
|
||||
}
|
||||
|
||||
std::ostream& reset(std::ostream& s) {
|
||||
#ifdef _WIN32
|
||||
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), reset_ter_color.scr.wAttributes);
|
||||
#else
|
||||
s<<"\033[0m";
|
||||
#endif
|
||||
return s;
|
||||
}
|
||||
|
||||
void flstream::load(const std::string& f) {
|
||||
if (file==f) { // don't need to load a loaded file
|
||||
return;
|
||||
} else {
|
||||
file=f;
|
||||
}
|
||||
|
||||
res.clear();
|
||||
std::ifstream in(f, std::ios::binary);
|
||||
if (in.fail()) {
|
||||
std::cerr<<red<<"src: "<<reset<<"cannot open <"<<f<<">\n";
|
||||
std::exit(1);
|
||||
}
|
||||
|
||||
while(!in.eof()) {
|
||||
std::string line;
|
||||
std::getline(in, line);
|
||||
res.push_back(line);
|
||||
}
|
||||
}
|
||||
|
||||
void error::fatal(const std::string& stage, const std::string& info) {
|
||||
std::cerr<<red<<stage<<": "<<white<<info<<reset<<"\n";
|
||||
if (file.length()) {
|
||||
std::cerr<<cyan<<" --> "<<red<<file<<reset<<"\n\n";
|
||||
} else {
|
||||
std::cerr<<reset<<"\n";
|
||||
}
|
||||
std::exit(1);
|
||||
}
|
||||
|
||||
void error::err(const std::string& stage, const std::string& info) {
|
||||
++cnt;
|
||||
std::cerr<<red<<stage<<": "<<white<<info<<reset<<"\n";
|
||||
if (file.length()) {
|
||||
std::cerr<<cyan<<" --> "<<red<<file<<reset<<"\n\n";
|
||||
} else {
|
||||
std::cerr<<reset<<"\n";
|
||||
}
|
||||
}
|
||||
|
||||
void error::err(
|
||||
const std::string& stage, const span& loc, const std::string& info) {
|
||||
// load error occurred file into string lines
|
||||
load(loc.file);
|
||||
|
||||
++cnt;
|
||||
|
||||
std::cerr
|
||||
<<red<<stage<<": "<<white<<info<<reset<<"\n"<<cyan<<" --> "
|
||||
<<red<<loc.file<<":"<<loc.begin_line<<":"<<loc.begin_column+1<<reset<<"\n";
|
||||
|
||||
const usize maxlen = std::to_string(loc.end_line).length();
|
||||
const std::string iden = identation(maxlen);
|
||||
|
||||
for(u32 line=loc.begin_line; line<=loc.end_line; ++line) {
|
||||
if (!line) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (loc.begin_line<line && line<loc.end_line) {
|
||||
if (line==loc.begin_line+1) {
|
||||
std::cerr<<cyan<<iden<<" | "<<reset<<"...\n"<<cyan<<iden<<" | "<<reset<<"\n";
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// if this line has nothing, skip
|
||||
if (!res[line-1].length() && line!=loc.end_line) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const std::string& code=res[line-1];
|
||||
std::cerr<<cyan<<leftpad(line, maxlen)<<" | "<<reset<<code<<"\n";
|
||||
// output underline
|
||||
std::cerr<<cyan<<iden<<" | "<<reset;
|
||||
if (loc.begin_line==loc.end_line) {
|
||||
for(u32 i=0; i<loc.begin_column; ++i) {
|
||||
std::cerr<<char(" \t"[code[i]=='\t']);
|
||||
}
|
||||
for(u32 i=loc.begin_column ;i<loc.end_column; ++i) {
|
||||
std::cerr<<red<<(code[i]=='\t'?"^^^^":"^")<<reset;
|
||||
}
|
||||
} else if (line==loc.begin_line) {
|
||||
for(u32 i=0; i<loc.begin_column; ++i) {
|
||||
std::cerr<<char(" \t"[code[i]=='\t']);
|
||||
}
|
||||
for(u32 i=loc.begin_column; i<code.size(); ++i) {
|
||||
std::cerr<<red<<(code[i]=='\t'?"^^^^":"^")<<reset;
|
||||
}
|
||||
} else if (loc.begin_line<line && line<loc.end_line) {
|
||||
for(u32 i=0; i<code.size(); ++i) {
|
||||
std::cerr<<red<<(code[i]=='\t'?"^^^^":"^");
|
||||
}
|
||||
} else {
|
||||
for(u32 i=0; i<loc.end_column; ++i) {
|
||||
std::cerr<<red<<(code[i]=='\t'?"^^^^":"^");
|
||||
}
|
||||
}
|
||||
if (line==loc.end_line) {
|
||||
std::cerr<<reset;
|
||||
} else {
|
||||
std::cerr<<reset<<"\n";
|
||||
}
|
||||
}
|
||||
std::cerr<<"\n\n";
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream> // MSVC need this to use std::getline
|
||||
#include <cstring>
|
||||
#include <vector>
|
||||
|
||||
#include "nasal_new_header.h"
|
||||
|
||||
struct span {
|
||||
u32 begin_line;
|
||||
u32 begin_column;
|
||||
u32 end_line;
|
||||
u32 end_column;
|
||||
std::string file;
|
||||
};
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h> // use SetConsoleTextAttribute
|
||||
struct for_reset {
|
||||
CONSOLE_SCREEN_BUFFER_INFO scr;
|
||||
for_reset() {
|
||||
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &scr);
|
||||
}
|
||||
} reset_ter_color;
|
||||
#endif
|
||||
|
||||
std::ostream& back_white(std::ostream&);
|
||||
std::ostream& red(std::ostream&);
|
||||
std::ostream& cyan(std::ostream&);
|
||||
std::ostream& orange(std::ostream&);
|
||||
std::ostream& white(std::ostream&);
|
||||
std::ostream& reset(std::ostream&);
|
||||
|
||||
class flstream {
|
||||
protected:
|
||||
std::string file;
|
||||
std::vector<std::string> res;
|
||||
public:
|
||||
flstream():file("") {}
|
||||
void load(const std::string&);
|
||||
const std::string& operator[](usize n) const {return res[n];}
|
||||
const std::string& name() const {return file;}
|
||||
usize size() const {return res.size();}
|
||||
};
|
||||
|
||||
class error:public flstream {
|
||||
private:
|
||||
u32 cnt; // counter for errors
|
||||
|
||||
std::string identation(usize len) {
|
||||
return std::string(len,' ');
|
||||
}
|
||||
std::string leftpad(u32 num, usize len) {
|
||||
auto tmp = std::to_string(num);
|
||||
while(tmp.length()<len) {
|
||||
tmp=" "+tmp;
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
public:
|
||||
error():cnt(0) {}
|
||||
void fatal(const std::string&, const std::string&);
|
||||
void err(const std::string&, const std::string&);
|
||||
void err(const std::string&, const span&, const std::string&);
|
||||
|
||||
void chkerr() const {
|
||||
if (cnt) {
|
||||
std::exit(1);
|
||||
}
|
||||
}
|
||||
};
|
|
@ -0,0 +1,51 @@
|
|||
#pragma once
|
||||
|
||||
#ifndef __nasver
|
||||
#define __nasver "10.1"
|
||||
#endif
|
||||
|
||||
#include <cstdint>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <cstring>
|
||||
#include <cmath>
|
||||
#include <vector>
|
||||
|
||||
bool is_windows();
|
||||
bool is_linux();
|
||||
bool is_macos();
|
||||
bool is_x86();
|
||||
bool is_amd64();
|
||||
bool is_x86_64();
|
||||
bool is_arm();
|
||||
bool is_aarch64();
|
||||
bool is_ia64();
|
||||
bool is_powerpc();
|
||||
bool is_superh();
|
||||
|
||||
using i32 = std::int32_t;
|
||||
using i64 = std::int64_t;
|
||||
using u8 = std::uint8_t;
|
||||
using u16 = std::uint16_t;
|
||||
using u32 = std::uint32_t;
|
||||
using u64 = std::uint64_t;
|
||||
using usize = std::size_t;
|
||||
using f64 = double;
|
||||
|
||||
const u32 STACK_DEPTH=1024;
|
||||
|
||||
f64 hex2f(const char*);
|
||||
f64 oct2f(const char*);
|
||||
|
||||
// we have the same reason not using atof here
|
||||
// just as andy's interpreter does.
|
||||
// it is not platform independent, and may have strange output.
|
||||
// so we write a new function here to convert str to number manually.
|
||||
// but this also makes 0.1+0.2==0.3,
|
||||
// not another result that you may get in other languages.
|
||||
f64 dec2f(const char*);
|
||||
|
||||
f64 str2num(const char*);
|
||||
i32 utf8_hdchk(const char);
|
||||
std::string chrhex(const char);
|
||||
std::string rawstr(const std::string&, const usize maxlen=0);
|
|
@ -59,7 +59,7 @@ void lexer::err_char() {
|
|||
err.fatal("lexer", "fatal error occurred, stop");
|
||||
}
|
||||
|
||||
void lexer::open(const string& file) {
|
||||
void lexer::open(const std::string& file) {
|
||||
// check file exsits and it is a regular file
|
||||
struct stat buffer;
|
||||
if (stat(file.c_str(), &buffer)==0 && !S_ISREG(buffer.st_mode)) {
|
||||
|
@ -80,14 +80,14 @@ void lexer::open(const string& file) {
|
|||
res=ss.str();
|
||||
}
|
||||
|
||||
tok lexer::get_type(const string& str) {
|
||||
tok lexer::get_type(const std::string& str) {
|
||||
return typetbl.count(str)?typetbl.at(str):tok::null;
|
||||
}
|
||||
|
||||
string lexer::utf8_gen() {
|
||||
string str="";
|
||||
std::string lexer::utf8_gen() {
|
||||
std::string str="";
|
||||
while(ptr<res.size() && res[ptr]<0) {
|
||||
string tmp="";
|
||||
std::string tmp="";
|
||||
u32 nbytes=utf8_hdchk(res[ptr]);
|
||||
if (!nbytes) {
|
||||
++ptr;
|
||||
|
@ -105,7 +105,7 @@ string lexer::utf8_gen() {
|
|||
// utf8 character's total length is 1+nbytes
|
||||
if (tmp.length()!=1+nbytes) {
|
||||
++column;
|
||||
string utf_info="0x"+chrhex(tmp[0]);
|
||||
std::string utf_info="0x"+chrhex(tmp[0]);
|
||||
for(u32 i=1;i<tmp.size();++i) {
|
||||
utf_info+=" 0x"+chrhex(tmp[i]);
|
||||
}
|
||||
|
@ -121,7 +121,7 @@ string lexer::utf8_gen() {
|
|||
token lexer::id_gen() {
|
||||
u32 begin_line=line;
|
||||
u32 begin_column=column;
|
||||
string str="";
|
||||
std::string str="";
|
||||
while(ptr<res.size() && (is_id(res[ptr])||is_dec(res[ptr]))) {
|
||||
if (res[ptr]<0) { // utf-8
|
||||
str+=utf8_gen();
|
||||
|
@ -139,7 +139,7 @@ token lexer::num_gen() {
|
|||
u32 begin_column=column;
|
||||
// generate hex number
|
||||
if (ptr+1<res.size() && res[ptr]=='0' && res[ptr+1]=='x') {
|
||||
string str="0x";
|
||||
std::string str="0x";
|
||||
ptr+=2;
|
||||
while(ptr<res.size() && is_hex(res[ptr])) {
|
||||
str+=res[ptr++];
|
||||
|
@ -150,7 +150,7 @@ token lexer::num_gen() {
|
|||
}
|
||||
return {{begin_line, begin_column, line, column, filename}, tok::num, str};
|
||||
} else if (ptr+1<res.size() && res[ptr]=='0' && res[ptr+1]=='o') { // generate oct number
|
||||
string str="0o";
|
||||
std::string str="0o";
|
||||
ptr+=2;
|
||||
while(ptr<res.size() && is_oct(res[ptr])) {
|
||||
str+=res[ptr++];
|
||||
|
@ -168,7 +168,7 @@ token lexer::num_gen() {
|
|||
}
|
||||
// generate dec number
|
||||
// dec number -> [0~9][0~9]*(.[0~9]*)(e|E(+|-)0|[1~9][0~9]*)
|
||||
string str="";
|
||||
std::string str="";
|
||||
while(ptr<res.size() && is_dec(res[ptr])) {
|
||||
str+=res[ptr++];
|
||||
}
|
||||
|
@ -206,7 +206,7 @@ token lexer::num_gen() {
|
|||
token lexer::str_gen() {
|
||||
u32 begin_line=line;
|
||||
u32 begin_column=column;
|
||||
string str="";
|
||||
std::string str="";
|
||||
const char begin=res[ptr];
|
||||
++column;
|
||||
while(++ptr<res.size() && res[ptr]!=begin) {
|
||||
|
@ -257,7 +257,7 @@ token lexer::str_gen() {
|
|||
token lexer::single_opr() {
|
||||
u32 begin_line=line;
|
||||
u32 begin_column=column;
|
||||
string str(1,res[ptr]);
|
||||
std::string str(1,res[ptr]);
|
||||
++column;
|
||||
tok type=get_type(str);
|
||||
if (type==tok::null) {
|
||||
|
@ -270,7 +270,7 @@ token lexer::single_opr() {
|
|||
token lexer::dots() {
|
||||
u32 begin_line=line;
|
||||
u32 begin_column=column;
|
||||
string str=".";
|
||||
std::string str=".";
|
||||
if (ptr+2<res.size() && res[ptr+1]=='.' && res[ptr+2]=='.') {
|
||||
str+="..";
|
||||
}
|
||||
|
@ -283,7 +283,7 @@ token lexer::calc_opr() {
|
|||
u32 begin_line=line;
|
||||
u32 begin_column=column;
|
||||
// get calculation operator
|
||||
string str(1,res[ptr++]);
|
||||
std::string str(1,res[ptr++]);
|
||||
if (ptr<res.size() && res[ptr]=='=') {
|
||||
str+=res[ptr++];
|
||||
}
|
||||
|
@ -291,7 +291,7 @@ token lexer::calc_opr() {
|
|||
return {{begin_line, begin_column, line, column, filename}, get_type(str), str};
|
||||
}
|
||||
|
||||
const error& lexer::scan(const string& file) {
|
||||
const error& lexer::scan(const std::string& file) {
|
||||
line=1;
|
||||
column=0;
|
||||
ptr=0;
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
#include <unordered_map>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "nasal.h"
|
||||
#include "nasal_err.h"
|
||||
#include "nasal_new_header.h"
|
||||
#include "nasal_new_err.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define S_ISREG(m) (((m)&0xF000)==0x8000)
|
||||
|
@ -83,7 +83,7 @@ enum class tok:u32 {
|
|||
struct token {
|
||||
span loc; // location
|
||||
tok type; // token type
|
||||
string str; // content
|
||||
std::string str; // content
|
||||
token() = default;
|
||||
token(const token&) = default;
|
||||
};
|
||||
|
@ -93,11 +93,11 @@ private:
|
|||
u32 line;
|
||||
u32 column;
|
||||
usize ptr;
|
||||
string filename;
|
||||
string res;
|
||||
std::string filename;
|
||||
std::string res;
|
||||
error& err;
|
||||
std::vector<token> toks;
|
||||
const std::unordered_map<string,tok> typetbl {
|
||||
const std::unordered_map<std::string, tok> typetbl {
|
||||
{"true" ,tok::tktrue },
|
||||
{"false" ,tok::tkfalse },
|
||||
{"for" ,tok::rfor },
|
||||
|
@ -153,7 +153,7 @@ private:
|
|||
{">=" ,tok::geq }
|
||||
};
|
||||
|
||||
tok get_type(const string&);
|
||||
tok get_type(const std::string&);
|
||||
bool skip(char);
|
||||
bool is_id(char);
|
||||
bool is_hex(char);
|
||||
|
@ -166,8 +166,8 @@ private:
|
|||
void skip_note();
|
||||
void err_char();
|
||||
|
||||
void open(const string&);
|
||||
string utf8_gen();
|
||||
void open(const std::string&);
|
||||
std::string utf8_gen();
|
||||
token id_gen();
|
||||
token num_gen();
|
||||
token str_gen();
|
||||
|
@ -175,7 +175,9 @@ private:
|
|||
token dots();
|
||||
token calc_opr();
|
||||
public:
|
||||
lexer(error& e): line(1), column(0), ptr(0), filename(""), res(""), err(e) {}
|
||||
const error& scan(const string&);
|
||||
lexer(error& e):
|
||||
line(1), column(0),
|
||||
ptr(0), filename(""), res(""), err(e) {}
|
||||
const error& scan(const std::string&);
|
||||
const std::vector<token>& result() const {return toks;}
|
||||
};
|
||||
|
|
|
@ -1,15 +1,9 @@
|
|||
#include "nasal.h"
|
||||
#include "nasal_err.h"
|
||||
#include "nasal_lexer.h"
|
||||
#include "nasal_ast.h"
|
||||
#include "nasal_parse.h"
|
||||
#include "nasal_import.h"
|
||||
#include "nasal_opt.h"
|
||||
#include "nasal_gc.h"
|
||||
#include "nasal_builtin.h"
|
||||
#include "nasal_codegen.h"
|
||||
#include "nasal_vm.h"
|
||||
#include "nasal_dbg.h"
|
||||
#include "nasal_new_header.h"
|
||||
#include "nasal_new_err.h"
|
||||
#include "nasal_new_lexer.h"
|
||||
#include "nasal_new_ast.h"
|
||||
#include "nasal_new_parse.h"
|
||||
#include "ast_visitor.h"
|
||||
|
||||
#include <unordered_map>
|
||||
#include <thread>
|
||||
|
@ -73,8 +67,8 @@ void err() {
|
|||
}
|
||||
|
||||
void execute(
|
||||
const string& file,
|
||||
const std::vector<string>& argv,
|
||||
const std::string& file,
|
||||
const std::vector<std::string>& argv,
|
||||
const u32 cmd
|
||||
) {
|
||||
using clk=std::chrono::high_resolution_clock;
|
||||
|
@ -83,9 +77,9 @@ void execute(
|
|||
error err;
|
||||
lexer lex(err);
|
||||
parse parse(err);
|
||||
linker ld(err);
|
||||
codegen gen(err);
|
||||
vm ctx;
|
||||
// linker ld(err);
|
||||
// codegen gen(err);
|
||||
// vm ctx;
|
||||
|
||||
// lexer scans file to get tokens
|
||||
lex.scan(file).chkerr();
|
||||
|
@ -94,27 +88,27 @@ void execute(
|
|||
parse.compile(lex).chkerr();
|
||||
|
||||
// linker gets parser's ast and load import files to this ast
|
||||
ld.link(parse, file, cmd&VM_DETAIL).chkerr();
|
||||
// ld.link(parse, file, cmd&VM_DETAIL).chkerr();
|
||||
|
||||
// optimizer does simple optimization on ast
|
||||
optimize(parse.tree());
|
||||
if (cmd&VM_AST) {
|
||||
parse.tree().dump();
|
||||
}
|
||||
// optimize(parse.tree());
|
||||
// if (cmd&VM_AST) {
|
||||
// parse.tree().dump();
|
||||
// }
|
||||
|
||||
// code generator gets parser's ast and import file list to generate code
|
||||
gen.compile(parse, ld).chkerr();
|
||||
if (cmd&VM_CODE) {
|
||||
gen.print();
|
||||
}
|
||||
// gen.compile(parse, ld).chkerr();
|
||||
// if (cmd&VM_CODE) {
|
||||
// gen.print();
|
||||
// }
|
||||
|
||||
// run
|
||||
auto start=clk::now();
|
||||
if (cmd&VM_DEBUG) {
|
||||
dbg(err).run(gen, ld, argv);
|
||||
} else if (cmd&VM_TIME || cmd&VM_EXEC) {
|
||||
ctx.run(gen, ld, argv, cmd&VM_DETAIL);
|
||||
}
|
||||
// if (cmd&VM_DEBUG) {
|
||||
// dbg(err).run(gen, ld, argv);
|
||||
// } else if (cmd&VM_TIME || cmd&VM_EXEC) {
|
||||
// ctx.run(gen, ld, argv, cmd&VM_DETAIL);
|
||||
// }
|
||||
|
||||
// get running time
|
||||
if (cmd&VM_TIME) {
|
||||
|
@ -132,7 +126,7 @@ i32 main(i32 argc, const char* argv[]) {
|
|||
|
||||
// run directly or show help
|
||||
if (argc==2) {
|
||||
string s(argv[1]);
|
||||
std::string s(argv[1]);
|
||||
if (s=="-h" || s=="--help") {
|
||||
std::clog<<help;
|
||||
} else if (s[0]!='-') {
|
||||
|
@ -144,7 +138,7 @@ i32 main(i32 argc, const char* argv[]) {
|
|||
}
|
||||
|
||||
// execute with arguments
|
||||
const std::unordered_map<string,u32> cmdlst={
|
||||
const std::unordered_map<std::string,u32> cmdlst = {
|
||||
{"--ast", VM_AST},
|
||||
{"-a", VM_AST},
|
||||
{"--code", VM_CODE},
|
||||
|
@ -159,8 +153,8 @@ i32 main(i32 argc, const char* argv[]) {
|
|||
{"-dbg", VM_DEBUG}
|
||||
};
|
||||
u32 cmd=0;
|
||||
string filename="";
|
||||
std::vector<string> vm_argv;
|
||||
std::string filename="";
|
||||
std::vector<std::string> vm_argv;
|
||||
for(i32 i=1; i<argc; ++i) {
|
||||
if (cmdlst.count(argv[i])) {
|
||||
cmd|=cmdlst.at(argv[i]);
|
|
@ -0,0 +1,230 @@
|
|||
#include "nasal_new_header.h"
|
||||
|
||||
bool is_windows() {
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool is_linux() {
|
||||
#if defined __linux__
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool is_macos() {
|
||||
#if defined __APPLE__
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool is_x86() {
|
||||
#if defined(__i386__) || defined(_M_IX86)
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool is_amd64() {
|
||||
#if defined(__amd64__) || defined(_M_X64)
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool is_x86_64() {
|
||||
return is_amd64();
|
||||
}
|
||||
|
||||
bool is_arm() {
|
||||
#if defined(__arm__) || defined(_M_ARM)
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool is_aarch64() {
|
||||
#if defined(__aarch64__) || defined(_M_ARM64)
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool is_ia64() {
|
||||
#if defined(__ia64__)
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool is_powerpc() {
|
||||
#if defined(__powerpc__)
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool is_superh() {
|
||||
#if defined(__sh__)
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
f64 hex2f(const char* str) {
|
||||
f64 ret=0;
|
||||
for(; *str; ++str) {
|
||||
if ('0'<=*str && *str<='9') {
|
||||
ret=ret*16+(*str-'0');
|
||||
} else if ('a'<=*str && *str<='f') {
|
||||
ret=ret*16+(*str-'a'+10);
|
||||
} else if ('A'<=*str && *str<='F') {
|
||||
ret=ret*16+(*str-'A'+10);
|
||||
} else {
|
||||
return nan("");
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
f64 oct2f(const char* str) {
|
||||
f64 ret=0;
|
||||
while('0'<=*str && *str<'8') {
|
||||
ret=ret*8+(*str++-'0');
|
||||
}
|
||||
if (*str) {
|
||||
return nan("");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// we have the same reason not using atof here
|
||||
// just as andy's interpreter does.
|
||||
// it is not platform independent, and may have strange output.
|
||||
// so we write a new function here to convert str to number manually.
|
||||
// but this also makes 0.1+0.2==0.3,
|
||||
// not another result that you may get in other languages.
|
||||
f64 dec2f(const char* str) {
|
||||
f64 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;
|
||||
while('0'<=*str && *str<='9') {
|
||||
num_pow=num_pow*10+(*str++-'0');
|
||||
}
|
||||
if (*str) {
|
||||
return nan("");
|
||||
}
|
||||
return ret*std::pow(10,negative*num_pow);
|
||||
}
|
||||
|
||||
f64 str2num(const char* str) {
|
||||
bool negative=false;
|
||||
f64 res=0;
|
||||
if (*str=='-' || *str=='+') {
|
||||
negative=(*str++=='-');
|
||||
}
|
||||
if (!*str) {
|
||||
return nan("");
|
||||
}
|
||||
if (str[0]=='0' && str[1]=='x') {
|
||||
res=hex2f(str+2);
|
||||
} else if (str[0]=='0' && str[1]=='o') {
|
||||
res=oct2f(str+2);
|
||||
} else {
|
||||
res=dec2f(str);
|
||||
}
|
||||
return negative?-res:res;
|
||||
}
|
||||
|
||||
i32 utf8_hdchk(const char head) {
|
||||
// RFC-2279 but now we use RFC-3629 so nbytes is less than 4
|
||||
const u8 c=(u8)head;
|
||||
if ((c>>5)==0x06) { // 110x xxxx (10xx xxxx)^1
|
||||
return 1;
|
||||
}
|
||||
if ((c>>4)==0x0e) { // 1110 xxxx (10xx xxxx)^2
|
||||
return 2;
|
||||
}
|
||||
if ((c>>3)==0x1e) { // 1111 0xxx (10xx xxxx)^3
|
||||
return 3;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string chrhex(const char c) {
|
||||
const char hextbl[]="0123456789abcdef";
|
||||
return {hextbl[(c&0xf0)>>4],hextbl[c&0x0f]};
|
||||
}
|
||||
|
||||
std::string rawstr(const std::string& str, const usize maxlen) {
|
||||
std::string ret("");
|
||||
for(auto i:str) {
|
||||
// windows doesn't output unicode normally, so we output the hex
|
||||
if (is_windows() && i<=0) {
|
||||
ret+="\\x"+chrhex(i);
|
||||
continue;
|
||||
}
|
||||
switch(i) {
|
||||
case '\0': ret+="\\0"; break;
|
||||
case '\a': ret+="\\a"; break;
|
||||
case '\b': ret+="\\b"; 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 '\033':ret+="\\e"; break;
|
||||
case '\"': ret+="\\\"";break;
|
||||
case '\'': ret+="\\\'";break;
|
||||
case '\\': ret+="\\\\";break;
|
||||
default: ret+=i; break;
|
||||
}
|
||||
}
|
||||
if (maxlen && ret.length()>maxlen) {
|
||||
ret=ret.substr(0,maxlen)+"...";
|
||||
}
|
||||
return ret;
|
||||
}
|
|
@ -129,17 +129,10 @@ bool parse::check_func_end(expr* node) {
|
|||
type==expr_type::ast_hash) {
|
||||
return false;
|
||||
}
|
||||
if (node.child().empty() || (
|
||||
type!=expr_type::ast_def &&
|
||||
type!=expr_type::ast_equal &&
|
||||
type!=expr_type::ast_addeq &&
|
||||
type!=expr_type::ast_subeq &&
|
||||
type!=expr_type::ast_multeq &&
|
||||
type!=expr_type::ast_diveq &&
|
||||
type!=expr_type::ast_lnkeq)) {
|
||||
return false;
|
||||
} else {
|
||||
return check_func_end(node.child().back());
|
||||
if (type==expr_type::ast_def) {
|
||||
return check_func_end(((definition_expr*)type)->get_value());
|
||||
} else if (type==expr_type::ast_assign) {
|
||||
return check_func_end(((assignment_expr*)type)->get_right());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -301,7 +294,6 @@ void parse::params(function* func_node) {
|
|||
auto param = new parameter(toks[ptr].loc);
|
||||
param->set_parameter_name(id());
|
||||
if (lookahead(tok::eq) || lookahead(tok::ellipsis)) {
|
||||
ast special_arg(toks[ptr].loc, ast_null);
|
||||
if (lookahead(tok::eq)) {
|
||||
match(tok::eq);
|
||||
param->set_parameter_type(parameter::param_type::default_parameter);
|
||||
|
@ -417,16 +409,31 @@ expr* parse::calc() {
|
|||
node = tmp;
|
||||
} else if (tok::eq<=toks[ptr].type && toks[ptr].type<=tok::lnkeq) {
|
||||
// tok::eq~tok::lnkeq is 37 to 42,ast_equal~ast_lnkeq is 21~26
|
||||
ast tmp(toks[ptr].loc, (u32)toks[ptr].type-(u32)tok::eq+ast_equal);
|
||||
tmp.add(std::move(node));
|
||||
auto tmp = new assignment_expr(toks[ptr].loc);
|
||||
switch(toks[ptr].type) {
|
||||
case tok::eq: tmp->set_type(assignment_expr::assign_type::equal); break;
|
||||
case tok::addeq: tmp->set_type(assignment_expr::assign_type::add_equal); break;
|
||||
case tok::subeq: tmp->set_type(assignment_expr::assign_type::sub_equal); break;
|
||||
case tok::multeq: tmp->set_type(assignment_expr::assign_type::mult_equal); break;
|
||||
case tok::diveq: tmp->set_type(assignment_expr::assign_type::div_equal); break;
|
||||
case tok::lnkeq: tmp->set_type(assignment_expr::assign_type::concat_equal); break;
|
||||
default: break;
|
||||
}
|
||||
tmp->set_left(node);
|
||||
match(toks[ptr].type);
|
||||
tmp.add(calc());
|
||||
tmp->set_right(calc());
|
||||
node = tmp;
|
||||
} else if (toks[ptr].type==tok::btandeq || toks[ptr].type==tok::btoreq || toks[ptr].type==tok::btxoreq) {
|
||||
ast tmp(toks[ptr].loc, (u32)toks[ptr].type-(u32)tok::btandeq+ast_btandeq);
|
||||
tmp.add(std::move(node));
|
||||
auto tmp = new assignment_expr(toks[ptr].loc);
|
||||
switch(toks[ptr].type) {
|
||||
case tok::btandeq: tmp->set_type(assignment_expr::assign_type::bitwise_and_equal); break;
|
||||
case tok::btoreq: tmp->set_type(assignment_expr::assign_type::bitwise_or_equal); break;
|
||||
case tok::btxoreq: tmp->set_type(assignment_expr::assign_type::bitwise_xor_equal); break;
|
||||
default: break;
|
||||
}
|
||||
tmp->set_left(node);
|
||||
match(toks[ptr].type);
|
||||
tmp.add(calc());
|
||||
tmp->set_right(calc());
|
||||
node = tmp;
|
||||
}
|
||||
update_location(node);
|
||||
|
|
|
@ -2,11 +2,10 @@
|
|||
|
||||
#include <unordered_map>
|
||||
|
||||
#include "nasal.h"
|
||||
#include "nasal_new_header.h"
|
||||
#include "nasal_new_ast.h"
|
||||
#include "nasal_lexer.h"
|
||||
#include "nasal_ast.h"
|
||||
#include "nasal_err.h"
|
||||
#include "nasal_new_lexer.h"
|
||||
#include "nasal_new_err.h"
|
||||
|
||||
class parse {
|
||||
|
||||
|
@ -22,7 +21,7 @@ private:
|
|||
error& err;
|
||||
|
||||
private:
|
||||
const std::unordered_map<tok,string> tokname {
|
||||
const std::unordered_map<tok, std::string> tokname {
|
||||
{tok::rfor ,"for" },
|
||||
{tok::forindex,"forindex"},
|
||||
{tok::foreach ,"foreach" },
|
||||
|
|
53
makefile
53
makefile
|
@ -18,24 +18,12 @@ SRC=\
|
|||
|
||||
STD=c++14
|
||||
|
||||
nasal:$(SRC) nasal_new_lexer.o nasal_new_ast.o nasal_new_parse.o ast_visitor.o
|
||||
nasal:$(SRC)
|
||||
$(CXX) -std=$(STD) -O3 main.cpp -o nasal -fno-exceptions -ldl -Wshadow -Wall
|
||||
|
||||
nasal.exe:$(SRC)
|
||||
$(CXX) -std=$(STD) -O3 main.cpp -o nasal.exe -fno-exceptions -Wshadow -Wall -static
|
||||
|
||||
nasal_new_lexer.o: ast/nasal_new_lexer.h ast/nasal_new_lexer.cpp nasal.h
|
||||
$(CXX) -std=$(STD) -c -O3 ast/nasal_new_lexer.cpp -fno-exceptions -fPIC -o nasal_new_lexer.o -I .
|
||||
|
||||
nasal_new_ast.o: ast/nasal_new_ast.h ast/nasal_new_ast.cpp nasal.h
|
||||
$(CXX) -std=$(STD) -c -O3 ast/nasal_new_ast.cpp -fno-exceptions -fPIC -o nasal_new_ast.o -I .
|
||||
|
||||
nasal_new_parse.o: ast/nasal_new_parse.h ast/nasal_new_parse.cpp nasal.h ast/nasal_new_ast.h
|
||||
# $(CXX) -std=$(STD) -c -O3 ast/nasal_new_parse.cpp -fno-exceptions -fPIC -o nasal_new_parse.o -I .
|
||||
|
||||
ast_visitor.o: ast/nasal_new_ast.h ast/ast_visitor.h ast/ast_visitor.cpp
|
||||
$(CXX) -std=$(STD) -c -O3 ast/ast_visitor.cpp -fno-exceptions -fPIC -o ast_visitor.o -I .
|
||||
|
||||
stable-release:$(SRC)
|
||||
$(CXX) -std=$(STD) -O2 main.cpp -o nasal -fno-exceptions -ldl -Wshadow -Wall
|
||||
|
||||
|
@ -84,3 +72,42 @@ test:nasal
|
|||
@ ./nasal -d test/wavecollapse.nas
|
||||
@ ./nasal test/word_collector.nas test/md5compare.nas
|
||||
@ ./nasal -t -d test/ycombinator.nas
|
||||
|
||||
NASAL_NEW_AST=\
|
||||
nasal_new_misc.o\
|
||||
nasal_new_err.o\
|
||||
nasal_new_lexer.o\
|
||||
nasal_new_ast.o\
|
||||
nasal_new_parse.o\
|
||||
ast_visitor.o\
|
||||
nasal_new_main.o
|
||||
|
||||
# for test
|
||||
nasal_new: $(NASAL_NEW_AST)
|
||||
$(CXX) $(NASAL_NEW_AST) -o nasal_new
|
||||
@ echo "build done"
|
||||
|
||||
nasal_new_main.o: ast/nasal_new_main.cpp
|
||||
$(CXX) -std=$(STD) -c -O3 ast/nasal_new_main.cpp -fno-exceptions -fPIC -o nasal_new_main.o -I .
|
||||
|
||||
nasal_new_misc.o: ast/nasal_new_header.h ast/nasal_new_misc.cpp
|
||||
$(CXX) -std=$(STD) -c -O3 ast/nasal_new_misc.cpp -fno-exceptions -fPIC -o nasal_new_misc.o -I .
|
||||
|
||||
nasal_new_err.o: ast/nasal_new_err.h ast/nasal_new_err.cpp
|
||||
$(CXX) -std=$(STD) -c -O3 ast/nasal_new_err.cpp -fno-exceptions -fPIC -o nasal_new_err.o -I .
|
||||
|
||||
nasal_new_lexer.o: ast/nasal_new_lexer.h ast/nasal_new_lexer.cpp
|
||||
$(CXX) -std=$(STD) -c -O3 ast/nasal_new_lexer.cpp -fno-exceptions -fPIC -o nasal_new_lexer.o -I .
|
||||
|
||||
nasal_new_ast.o: ast/nasal_new_ast.h ast/nasal_new_ast.cpp
|
||||
$(CXX) -std=$(STD) -c -O3 ast/nasal_new_ast.cpp -fno-exceptions -fPIC -o nasal_new_ast.o -I .
|
||||
|
||||
nasal_new_parse.o: ast/nasal_new_parse.h ast/nasal_new_parse.cpp ast/nasal_new_ast.h
|
||||
$(CXX) -std=$(STD) -c -O3 ast/nasal_new_parse.cpp -fno-exceptions -fPIC -o nasal_new_parse.o -I .
|
||||
|
||||
ast_visitor.o: ast/nasal_new_ast.h ast/ast_visitor.h ast/ast_visitor.cpp
|
||||
$(CXX) -std=$(STD) -c -O3 ast/ast_visitor.cpp -fno-exceptions -fPIC -o ast_visitor.o -I .
|
||||
|
||||
.PHONY: nasal_new_clean
|
||||
nasal_new_clean:
|
||||
rm $(NASAL_NEW_AST)
|
Loading…
Reference in New Issue