more things!
This commit is contained in:
@@ -8,6 +8,8 @@ set binDir=bin
|
||||
mkdir quickbuild 2>nul
|
||||
pushd quickbuild
|
||||
|
||||
taskkill /F /IM %exeName% > NUL 2> NUL
|
||||
|
||||
echo ---------- Compiling ----------
|
||||
call timecmd cl ../src/main.c /Fe%exeName% /W3 /TC /nologo /EHsc /Z7 /link /incremental /debug:fastlink
|
||||
|
||||
|
||||
+9
-7
@@ -1,11 +1,13 @@
|
||||
void assert_type (Ast_Node* node, Ast_Node_Type type) {
|
||||
if (node->type == type) return;
|
||||
|
||||
char *wanted, *got, *message;
|
||||
wanted = Ast_Node_Type_to_string(type);
|
||||
got = Ast_Node_Type_to_string(node->type);
|
||||
asprintf(&message, "Type assertion failed:\n\t"
|
||||
"Wanted: %s\n\t"
|
||||
"Got : %s\n", wanted, got);
|
||||
panic(message);
|
||||
/* char *wanted, *got, *message; */
|
||||
/* wanted = Ast_Node_Type_to_string(type); */
|
||||
/* got = Ast_Node_Type_to_string(node->type); */
|
||||
/* asprintf(&message, "Type assertion failed:\n\t" */
|
||||
/* "Wanted: %s\n\t" */
|
||||
/* "Got : %s\n", wanted, got); */
|
||||
/* panic(message); */
|
||||
|
||||
create_error(Error_Type_Type_Missmatch, node);
|
||||
}
|
||||
|
||||
+78
-7
@@ -1,7 +1,66 @@
|
||||
bool ast_node_equal(Ast_Node* n1, Ast_Node* n2) {
|
||||
if (n1 == n2)
|
||||
return true;
|
||||
if (n1->type != n2->type)
|
||||
return false;
|
||||
|
||||
switch (n1->type) {
|
||||
case Ast_Node_Type_Built_In_Function:
|
||||
return string_equal(
|
||||
n1->value.built_in_function->identifier,
|
||||
n2->value.built_in_function->identifier);
|
||||
case Ast_Node_Type_Function:
|
||||
// if they have the same pointer, true is
|
||||
// returned a few lines above
|
||||
return false;
|
||||
case Ast_Node_Type_Keyword:
|
||||
return string_equal(
|
||||
n1->value.keyword->identifier,
|
||||
n2->value.keyword->identifier);
|
||||
case Ast_Node_Type_Nil:
|
||||
return true;
|
||||
case Ast_Node_Type_Number:
|
||||
return
|
||||
n1->value.number->value ==
|
||||
n2->value.number->value;
|
||||
case Ast_Node_Type_Pair:
|
||||
create_error(Error_Type_Not_Yet_Implemented, n1);
|
||||
return false;
|
||||
case Ast_Node_Type_String:
|
||||
return string_equal(
|
||||
n1->value.string->value,
|
||||
n2->value.string->value);
|
||||
case Ast_Node_Type_Symbol:
|
||||
return string_equal(
|
||||
n1->value.symbol->identifier,
|
||||
n2->value.symbol->identifier);
|
||||
}
|
||||
|
||||
// we should never reach here
|
||||
return false;
|
||||
}
|
||||
|
||||
Ast_Node* built_in_equals(Ast_Node* operands) {
|
||||
if (operands->type == Ast_Node_Type_Nil)
|
||||
return create_ast_node_number(1);
|
||||
|
||||
Ast_Node* first = operands->value.pair->first;
|
||||
|
||||
while (operands->type == Ast_Node_Type_Pair) {
|
||||
if (!ast_node_equal(operands->value.pair->first, first))
|
||||
return create_ast_node_nil();
|
||||
operands = operands->value.pair->rest;
|
||||
}
|
||||
|
||||
return create_ast_node_number(1);
|
||||
}
|
||||
|
||||
Ast_Node* built_in_add(Ast_Node* operands) {
|
||||
double sum = 0;
|
||||
while (operands->type == Ast_Node_Type_Pair) {
|
||||
assert_type(operands->value.pair->first, Ast_Node_Type_Number);
|
||||
try {
|
||||
assert_type(operands->value.pair->first, Ast_Node_Type_Number);
|
||||
}
|
||||
sum += operands->value.pair->first->value.number->value;
|
||||
operands = operands->value.pair->rest;
|
||||
}
|
||||
@@ -10,12 +69,16 @@ Ast_Node* built_in_add(Ast_Node* operands) {
|
||||
}
|
||||
|
||||
Ast_Node* built_in_substract(Ast_Node* operands) {
|
||||
assert_type(operands->value.pair->first, Ast_Node_Type_Number);
|
||||
try {
|
||||
assert_type(operands->value.pair->first, Ast_Node_Type_Number);
|
||||
}
|
||||
double difference = operands->value.pair->first->value.number->value;
|
||||
|
||||
operands = operands->value.pair->rest;
|
||||
while (operands->type == Ast_Node_Type_Pair) {
|
||||
assert_type(operands->value.pair->first, Ast_Node_Type_Number);
|
||||
try {
|
||||
assert_type(operands->value.pair->first, Ast_Node_Type_Number);
|
||||
}
|
||||
|
||||
difference -= operands->value.pair->first->value.number->value;
|
||||
operands = operands->value.pair->rest;
|
||||
@@ -24,12 +87,16 @@ Ast_Node* built_in_substract(Ast_Node* operands) {
|
||||
}
|
||||
|
||||
Ast_Node* built_in_multiply(Ast_Node* operands) {
|
||||
assert_type(operands->value.pair->first, Ast_Node_Type_Number);
|
||||
try {
|
||||
assert_type(operands->value.pair->first, Ast_Node_Type_Number);
|
||||
}
|
||||
double product = operands->value.pair->first->value.number->value;
|
||||
|
||||
operands = operands->value.pair->rest;
|
||||
while (operands->type == Ast_Node_Type_Pair) {
|
||||
assert_type(operands->value.pair->first, Ast_Node_Type_Number);
|
||||
try {
|
||||
assert_type(operands->value.pair->first, Ast_Node_Type_Number);
|
||||
}
|
||||
|
||||
product *= operands->value.pair->first->value.number->value;
|
||||
operands = operands->value.pair->rest;
|
||||
@@ -38,12 +105,16 @@ Ast_Node* built_in_multiply(Ast_Node* operands) {
|
||||
}
|
||||
|
||||
Ast_Node* built_in_divide(Ast_Node* operands) {
|
||||
assert_type(operands->value.pair->first, Ast_Node_Type_Number);
|
||||
try {
|
||||
assert_type(operands->value.pair->first, Ast_Node_Type_Number);
|
||||
}
|
||||
double quotient = operands->value.pair->first->value.number->value;
|
||||
|
||||
operands = operands->value.pair->rest;
|
||||
while (operands->type == Ast_Node_Type_Pair) {
|
||||
assert_type(operands->value.pair->first, Ast_Node_Type_Number);
|
||||
try {
|
||||
assert_type(operands->value.pair->first, Ast_Node_Type_Number);
|
||||
}
|
||||
|
||||
quotient /= operands->value.pair->first->value.number->value;
|
||||
operands = operands->value.pair->rest;
|
||||
|
||||
@@ -12,7 +12,7 @@ typedef struct Environment Environment;
|
||||
Environment* create_empty_environment() {
|
||||
Environment* env = new(Environment);
|
||||
|
||||
int start_capacity = 1;
|
||||
int start_capacity = 16;
|
||||
|
||||
env->parent = nullptr;
|
||||
env->capacity = start_capacity;
|
||||
@@ -54,17 +54,17 @@ Ast_Node* lookup_symbol(Symbol* sym, Environment* env) {
|
||||
"+", "-", "*", "/",
|
||||
">", "<", "=", "<=", ">=",
|
||||
// Conditional stuff
|
||||
"if", "and", "or", "not",
|
||||
"if", "and", "or", "not",
|
||||
// Cons stuff
|
||||
"first", "rest", "pair",
|
||||
"pair", "first", "rest",
|
||||
// rest
|
||||
"load", "define",
|
||||
"lambda", "progn",
|
||||
"eval", "quote",
|
||||
"eval", "quote", "prog", "list",
|
||||
"print", "read",
|
||||
"help", "exit"
|
||||
"info", "type", "exit"
|
||||
};
|
||||
int built_in_count = 26;
|
||||
int built_in_count = sizeof(built_in_names) / sizeof(char*);
|
||||
|
||||
for (int i = 0; i < built_in_count; ++i) {
|
||||
if (string_equal(built_in_names[i], sym->identifier)) {
|
||||
|
||||
+159
-39
@@ -56,46 +56,84 @@ Ast_Node* eval_expr(Ast_Node* node, Environment* env) {
|
||||
case Ast_Node_Type_String:
|
||||
return node;
|
||||
case Ast_Node_Type_Pair: {
|
||||
Ast_Node* operator = eval_expr(node->value.pair->first, env);
|
||||
if (error) return nullptr;
|
||||
Ast_Node* operator;
|
||||
try {
|
||||
operator = eval_expr(node->value.pair->first, env);
|
||||
}
|
||||
|
||||
Ast_Node* operands = node->value.pair->rest;
|
||||
int operands_length;
|
||||
|
||||
|
||||
// check for built ins functions
|
||||
if (operator->type == Ast_Node_Type_Built_In_Function) {
|
||||
char* operator_name = operator->value.built_in_function->identifier;
|
||||
if (string_equal("quote", operator_name)) {
|
||||
int operands_length = list_length(operands);
|
||||
operands_length = list_length(operands);
|
||||
if (operands_length != 1) {
|
||||
report_error(Error_Type_Wrong_Number_Of_Arguments);
|
||||
}
|
||||
return operands->value.pair->first;
|
||||
} else if (string_equal("eval", operator_name)) {
|
||||
int operands_length = list_length(operands);
|
||||
try {
|
||||
operands_length = list_length(operands);
|
||||
}
|
||||
if (operands_length != 1) {
|
||||
report_error(Error_Type_Wrong_Number_Of_Arguments);
|
||||
}
|
||||
if (error) return nullptr;
|
||||
|
||||
return eval_expr(operands->value.pair->first, env);
|
||||
} else if (string_equal("prog", operator_name)) {
|
||||
if (operands->type == Ast_Node_Type_Nil)
|
||||
return operands;
|
||||
while (!error) {
|
||||
try {
|
||||
operands->value.pair->first = eval_expr(operands->value.pair->first, env);
|
||||
}
|
||||
|
||||
if (operands->value.pair->rest->type == Ast_Node_Type_Pair)
|
||||
operands = operands->value.pair->rest;
|
||||
else {
|
||||
if (operands->value.pair->rest->type != Ast_Node_Type_Nil)
|
||||
report_error(Error_Type_Ill_Formed_List);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return operands->value.pair->first;
|
||||
} else if (string_equal("list", operator_name)) {
|
||||
try {
|
||||
eval_operands(operands, env);
|
||||
}
|
||||
return operands;
|
||||
} else if (string_equal("=", operator_name)) {
|
||||
try {
|
||||
eval_operands(operands, env);
|
||||
}
|
||||
return built_in_equals(operands);
|
||||
} else if (string_equal("+", operator_name)) {
|
||||
eval_operands(operands, env);
|
||||
if (error) return nullptr;
|
||||
try {
|
||||
eval_operands(operands, env);
|
||||
}
|
||||
return built_in_add(operands);
|
||||
} else if (string_equal("-", operator_name)) {
|
||||
eval_operands(operands, env);
|
||||
if (error) return nullptr;
|
||||
try {
|
||||
eval_operands(operands, env);
|
||||
}
|
||||
return built_in_substract(operands);
|
||||
} else if (string_equal("*", operator_name)) {
|
||||
eval_operands(operands, env);
|
||||
if (error) return nullptr;
|
||||
try {
|
||||
eval_operands(operands, env);
|
||||
}
|
||||
return built_in_multiply(operands);
|
||||
} else if (string_equal("/", operator_name)) {
|
||||
eval_operands(operands, env);
|
||||
if (error) return nullptr;
|
||||
try {
|
||||
eval_operands(operands, env);
|
||||
}
|
||||
return built_in_divide(operands);
|
||||
} else if (string_equal("define", operator_name)) {
|
||||
int operands_length = list_length(operands);
|
||||
if (error) return nullptr;
|
||||
try {
|
||||
operands_length = list_length(operands);
|
||||
}
|
||||
if (operands_length != 2) {
|
||||
report_error(Error_Type_Wrong_Number_Of_Arguments);
|
||||
}
|
||||
@@ -110,14 +148,40 @@ Ast_Node* eval_expr(Ast_Node* node, Environment* env) {
|
||||
define_symbol(symbol, value, env);
|
||||
|
||||
return value;
|
||||
} else if (string_equal("type", operator_name)) {
|
||||
try {
|
||||
operands_length = list_length(operands);
|
||||
}
|
||||
if (operands_length != 1) {
|
||||
report_error(Error_Type_Wrong_Number_Of_Arguments);
|
||||
}
|
||||
try {
|
||||
eval_operands(operands, env);
|
||||
}
|
||||
Ast_Node_Type type = operands->value.pair->first->type;
|
||||
switch (type) {
|
||||
case Ast_Node_Type_Built_In_Function: return create_ast_node_keyword("built-in-function");
|
||||
case Ast_Node_Type_Function: return create_ast_node_keyword("dynamic-function");
|
||||
case Ast_Node_Type_Keyword: return create_ast_node_keyword("keyword");
|
||||
case Ast_Node_Type_Nil: return create_ast_node_keyword("nil");
|
||||
case Ast_Node_Type_Number: return create_ast_node_keyword("number");
|
||||
case Ast_Node_Type_Pair: return create_ast_node_keyword("pair");
|
||||
case Ast_Node_Type_String: return create_ast_node_keyword("string");
|
||||
case Ast_Node_Type_Symbol: return create_ast_node_keyword("symbol");
|
||||
}
|
||||
|
||||
} else if (string_equal("exit", operator_name)) {
|
||||
int operands_length = list_length(operands);
|
||||
if (error) return nullptr;
|
||||
try {
|
||||
operands_length = list_length(operands);
|
||||
}
|
||||
if (operands_length > 1) {
|
||||
report_error(Error_Type_Wrong_Number_Of_Arguments);
|
||||
}
|
||||
|
||||
if (operands_length == 1) {
|
||||
try {
|
||||
eval_operands(operands, env);
|
||||
}
|
||||
Ast_Node* error_code = operands->value.pair->first;
|
||||
if (error_code->type != Ast_Node_Type_Number)
|
||||
report_error(Error_Type_Type_Missmatch);
|
||||
@@ -127,26 +191,30 @@ Ast_Node* eval_expr(Ast_Node* node, Environment* env) {
|
||||
exit(0);
|
||||
|
||||
} else if (string_equal("print", operator_name)) {
|
||||
int operands_length = list_length(operands);
|
||||
if (error) return nullptr;
|
||||
try {
|
||||
operands_length = list_length(operands);
|
||||
}
|
||||
if (operands_length != 1) {
|
||||
report_error(Error_Type_Wrong_Number_Of_Arguments);
|
||||
}
|
||||
eval_operands(operands, env);
|
||||
if (error) return nullptr;
|
||||
try {
|
||||
eval_operands(operands, env);
|
||||
}
|
||||
print(operands->value.pair->first);
|
||||
printf("\n");
|
||||
return operands->value.pair->first;
|
||||
} else if (string_equal("read", operator_name)) {
|
||||
int operands_length = list_length(operands);
|
||||
if (error) return nullptr;
|
||||
try {
|
||||
operands_length = list_length(operands);
|
||||
}
|
||||
if (operands_length > 1) {
|
||||
report_error(Error_Type_Wrong_Number_Of_Arguments);
|
||||
}
|
||||
|
||||
if (operands_length == 1) {
|
||||
eval_operands(operands, env);
|
||||
if (error) return nullptr;
|
||||
try {
|
||||
eval_operands(operands, env);
|
||||
}
|
||||
Ast_Node* prompt = operands->value.pair->first;
|
||||
if (prompt->type == Ast_Node_Type_String)
|
||||
printf("%s", prompt->value.string->value);
|
||||
@@ -155,9 +223,54 @@ Ast_Node* eval_expr(Ast_Node* node, Environment* env) {
|
||||
}
|
||||
char* line = read_line();
|
||||
return create_ast_node_string(line, (int)strlen(line));
|
||||
} else if (string_equal("pair", operator_name)) {
|
||||
try {
|
||||
operands_length = list_length(operands);
|
||||
}
|
||||
if (operands_length != 2) {
|
||||
report_error(Error_Type_Wrong_Number_Of_Arguments);
|
||||
}
|
||||
try {
|
||||
eval_operands(operands, env);
|
||||
}
|
||||
|
||||
return create_ast_node_pair(operands->value.pair->first, operands->value.pair->rest->value.pair->first);
|
||||
} else if (string_equal("first", operator_name)) {
|
||||
try {
|
||||
operands_length = list_length(operands);
|
||||
}
|
||||
if (operands_length != 1) {
|
||||
report_error(Error_Type_Wrong_Number_Of_Arguments);
|
||||
}
|
||||
try {
|
||||
eval_operands(operands, env);
|
||||
}
|
||||
if (operands->value.pair->first->type == Ast_Node_Type_Nil)
|
||||
return create_ast_node_nil();
|
||||
if (operands->value.pair->first->type != Ast_Node_Type_Pair)
|
||||
report_error(Error_Type_Type_Missmatch);
|
||||
|
||||
return operands->value.pair->first->value.pair->first;
|
||||
} else if (string_equal("rest", operator_name)) {
|
||||
try {
|
||||
operands_length = list_length(operands);
|
||||
}
|
||||
if (operands_length != 1) {
|
||||
report_error(Error_Type_Wrong_Number_Of_Arguments);
|
||||
}
|
||||
try {
|
||||
eval_operands(operands, env);
|
||||
}
|
||||
if (operands->value.pair->first->type == Ast_Node_Type_Nil)
|
||||
return create_ast_node_nil();
|
||||
if (operands->value.pair->first->type != Ast_Node_Type_Pair)
|
||||
report_error(Error_Type_Type_Missmatch);
|
||||
|
||||
return operands->value.pair->first->value.pair->rest;
|
||||
} else if (string_equal("if", operator_name)) {
|
||||
int operands_length = list_length(operands);
|
||||
if (error) return nullptr;
|
||||
try {
|
||||
operands_length = list_length(operands);
|
||||
}
|
||||
if (operands_length != 2 && operands_length != 3) {
|
||||
report_error(Error_Type_Wrong_Number_Of_Arguments);
|
||||
}
|
||||
@@ -166,8 +279,10 @@ Ast_Node* eval_expr(Ast_Node* node, Environment* env) {
|
||||
Ast_Node* then_part = operands->value.pair->rest;
|
||||
Ast_Node* else_part = then_part->value.pair->rest;
|
||||
|
||||
bool truthy = is_truthy(condition, env);
|
||||
if (error) return nullptr;
|
||||
bool truthy;
|
||||
try {
|
||||
truthy = is_truthy(condition, env);
|
||||
}
|
||||
if (truthy)
|
||||
return eval_expr(then_part->value.pair->first, env);
|
||||
else if (operands_length == 3)
|
||||
@@ -180,8 +295,9 @@ Ast_Node* eval_expr(Ast_Node* node, Environment* env) {
|
||||
if (operands->type != Ast_Node_Type_Pair) {
|
||||
report_error(Error_Type_Ill_Formed_List);
|
||||
}
|
||||
result &= is_truthy(operands->value.pair->first, env);
|
||||
if (error) return nullptr;
|
||||
try {
|
||||
result &= is_truthy(operands->value.pair->first, env);
|
||||
}
|
||||
operands = operands->value.pair->rest;
|
||||
|
||||
if (!result) return create_ast_node_nil();
|
||||
@@ -195,8 +311,9 @@ Ast_Node* eval_expr(Ast_Node* node, Environment* env) {
|
||||
if (operands->type != Ast_Node_Type_Pair) {
|
||||
report_error(Error_Type_Ill_Formed_List);
|
||||
}
|
||||
result |= is_truthy(operands->value.pair->first, env);
|
||||
if (error) return nullptr;
|
||||
try {
|
||||
result |= is_truthy(operands->value.pair->first, env);
|
||||
}
|
||||
operands = operands->value.pair->rest;
|
||||
|
||||
if (result) return create_ast_node_number(1);;
|
||||
@@ -204,13 +321,16 @@ Ast_Node* eval_expr(Ast_Node* node, Environment* env) {
|
||||
|
||||
return create_ast_node_nil();
|
||||
} else if (string_equal("not", operator_name)) {
|
||||
if (list_length(operands) != 1) {
|
||||
if (!error)
|
||||
create_error(Error_Type_Wrong_Number_Of_Arguments, operands);
|
||||
return nullptr;
|
||||
try {
|
||||
operands_length = list_length(operands);
|
||||
}
|
||||
if (operands_length != 1) {
|
||||
report_error(Error_Type_Wrong_Number_Of_Arguments);
|
||||
}
|
||||
bool truthy;
|
||||
try {
|
||||
truthy = is_truthy(operands->value.pair->first, env);
|
||||
}
|
||||
bool truthy = is_truthy(operands->value.pair->first, env);
|
||||
if (error) return nullptr;
|
||||
if (truthy)
|
||||
return create_ast_node_nil();
|
||||
return create_ast_node_number(1);
|
||||
|
||||
+15
-1
@@ -1,6 +1,19 @@
|
||||
#define new(type) (type*)malloc(sizeof(type))
|
||||
#define nullptr NULL
|
||||
|
||||
#define concat_( a, b) a##b
|
||||
#define label(prefix, lnum) concat_(prefix,lnum)
|
||||
#define try \
|
||||
if (1) \
|
||||
goto label(body,__LINE__); \
|
||||
else \
|
||||
while (1) \
|
||||
if (1) { \
|
||||
if(error) return 0; \
|
||||
break; \
|
||||
} \
|
||||
else label(body,__LINE__):
|
||||
|
||||
typedef enum { false, true } bool;
|
||||
|
||||
int string_equal(char* a, char* b) {
|
||||
@@ -75,7 +88,7 @@ char* read_entire_file (char* filename) {
|
||||
}
|
||||
|
||||
char* read_line() {
|
||||
char * line = malloc(100), * linep = line;
|
||||
char* line = malloc(100), * linep = line;
|
||||
size_t lenmax = 100, len = lenmax;
|
||||
int c;
|
||||
|
||||
@@ -102,6 +115,7 @@ char* read_line() {
|
||||
if((*line++ = c) == '\n')
|
||||
break;
|
||||
}
|
||||
*line--; // we dont want the \n actually
|
||||
*line = '\0';
|
||||
return linep;
|
||||
}
|
||||
|
||||
+4
-3
@@ -250,9 +250,10 @@ Ast_Node_Array_List* parse_program(char* text) {
|
||||
while (text[index_in_text] != '\0') {
|
||||
switch (text[index_in_text]) {
|
||||
case '(': {
|
||||
Ast_Node* parsed = parse_expression(text, &index_in_text);
|
||||
if (error)
|
||||
return nullptr;
|
||||
Ast_Node* parsed;
|
||||
try {
|
||||
parsed = parse_expression(text, &index_in_text);
|
||||
}
|
||||
append_to_Ast_Node_Array_List(program, parsed);
|
||||
} break;
|
||||
case ';':
|
||||
|
||||
@@ -31,25 +31,53 @@
|
||||
#+RESULTS:
|
||||
: t
|
||||
|
||||
** TODO first (car)
|
||||
** TODO rest (cdr)
|
||||
** TODO pair (cons)
|
||||
** DONE first (car)
|
||||
CLOSED: [2018-10-08 Mo 20:28]
|
||||
** DONE rest (cdr)
|
||||
CLOSED: [2018-10-08 Mo 20:28]
|
||||
** DONE pair (cons)
|
||||
CLOSED: [2018-10-08 Mo 20:28]
|
||||
|
||||
** TODO load (import)
|
||||
** TODO define
|
||||
** DONE define
|
||||
CLOSED: [2018-10-08 Mo 20:28]
|
||||
** TODO lambda
|
||||
** TODO progn
|
||||
** TODO eval
|
||||
** TODO quote
|
||||
** TODO print
|
||||
** TODO read
|
||||
** TODO help
|
||||
** DONE eval
|
||||
CLOSED: [2018-10-08 Mo 20:28]
|
||||
** DONE quote
|
||||
CLOSED: [2018-10-08 Mo 20:28]
|
||||
|
||||
** DONE list
|
||||
CLOSED: [2018-10-08 Mo 21:06]
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(quote (cons 2 (cons 3 (cons 4 ()))))
|
||||
;; (cons 2 (cons 3 (cons 4 nil)))
|
||||
(quote (2 . (3 . (4 . ()))))
|
||||
;; (2 3 4)
|
||||
#+end_src
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(list (cons 2 (cons 3 (cons 4 ()))))
|
||||
;; ((2 3 4))
|
||||
(list (quote(2 . (3 . (4 . ())))))
|
||||
#+end_src
|
||||
|
||||
** DONE print
|
||||
CLOSED: [2018-10-08 Mo 20:28]
|
||||
** DONE read
|
||||
CLOSED: [2018-10-08 Mo 20:28]
|
||||
** DONE type
|
||||
CLOSED: [2018-10-08 Mo 21:30]
|
||||
|
||||
** TODO info
|
||||
|
||||
* Types
|
||||
- Symbol
|
||||
- Number
|
||||
- String
|
||||
- Cons-cell (list)
|
||||
- pair (cons-cell)
|
||||
- lambda function lambda
|
||||
- built-in function
|
||||
|
||||
@@ -63,3 +91,5 @@
|
||||
variable within an upper namespace it should
|
||||
infact change the environment even if the
|
||||
function exited
|
||||
|
||||
(progn (setq x 4)(* x 2))
|
||||
|
||||
Reference in New Issue
Block a user