+37
-21
@@ -17,6 +17,7 @@
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
(define (char-between ch lo hi)
|
(define (char-between ch lo hi)
|
||||||
(if (char>=? ch lo)
|
(if (char>=? ch lo)
|
||||||
(char<=? ch hi)
|
(char<=? ch hi)
|
||||||
@@ -33,36 +34,51 @@
|
|||||||
#f)))
|
#f)))
|
||||||
#f))
|
#f))
|
||||||
|
|
||||||
|
|
||||||
(define (word-char-p ch)
|
(define (word-char-p ch)
|
||||||
(if (alphanumericp ch)
|
(if (alphanumericp ch)
|
||||||
#t
|
#t
|
||||||
(char= ch #\_)))
|
#f))
|
||||||
|
|
||||||
|
|
||||||
(define editor-move-to-end-of-word (lambda () (
|
(define editor-move-to-end-of-word (lambda () (
|
||||||
(if (word-char-p (editor-read-char))
|
(if (word-char-p (editor-read-char))
|
||||||
((move-cursor "right")
|
((move-cursor "right")
|
||||||
(editor-move-to-end-of-word))
|
(editor-move-to-end-of-word))
|
||||||
))
|
))
|
||||||
))
|
))
|
||||||
|
|
||||||
|
(define enter-and-tab
|
||||||
|
(lambda ()
|
||||||
|
(editor-insert-new-line)
|
||||||
|
(let ((is-in (move-cursor "up")))
|
||||||
|
(do ((ch (editor-read-char) (editor-read-char)))
|
||||||
|
((and (not (char=? ch #\space)) is-in) #f)
|
||||||
|
(move-cursor "down")
|
||||||
|
(editor-insert-char " ")
|
||||||
|
(set! is-in (move-cursor "up")))
|
||||||
|
(move-cursor "down"))))
|
||||||
|
|
||||||
|
(add-prefix "user")
|
||||||
|
|
||||||
|
|
||||||
;; KEY MAPPING
|
|
||||||
|
|
||||||
(map-key "CTRL-q" editor-quit)
|
(map-key "CTRL-x" '(editor-set-prefix "user") "no-prefix")
|
||||||
(map-key "CTRL-d" editor-save)
|
(map-key "CTRL-g" '(editor-set-prefix "no-prefix") "user")
|
||||||
(map-key "ARROW-UP" '(move-cursor "up"))
|
(map-key "CTRL-c" editor-quit "user")
|
||||||
(map-key "ARROW-DOWN" '(move-cursor "down"))
|
(map-key "CTRL-s" editor-save "user")
|
||||||
(map-key "ARROW-RIGHT" '(move-cursor "right"))
|
(map-key "ARROW-UP" '(move-cursor "up") "no-prefix")
|
||||||
(map-key "ARROW-LEFT" '(move-cursor "left"))
|
(map-key "ARROW-DOWN" '(move-cursor "down") "no-prefix")
|
||||||
(map-key "ENTER" editor-insert-new-line)
|
(map-key "ARROW-RIGHT" '(move-cursor "right") "no-prefix")
|
||||||
(map-key "CTRL-a" move-cursor-beg-line)
|
(map-key "ARROW-LEFT" '(move-cursor "left") "no-prefix")
|
||||||
(map-key "CTRL-e" move-cursor-end-line)
|
(map-key "ENTER" enter-and-tab "no-prefix")
|
||||||
(map-key "BACKSPACE" editor-delete-previous-char)
|
(map-key "CTRL-a" move-cursor-beg-line "no-prefix")
|
||||||
(map-key "DEL" editor-delete-next-char)
|
(map-key "CTRL-e" move-cursor-end-line "no-prefix")
|
||||||
(map-key "PAGE-UP" move-cursor-page-up)
|
(map-key "BACKSPACE" editor-delete-previous-char "no-prefix")
|
||||||
(map-key "PAGE-DOWN" move-cursor-page-down)
|
(map-key "DEL" editor-delete-next-char "no-prefix")
|
||||||
(map-key "CTRL-o" editor-open-file)
|
(map-key "PAGE-UP" move-cursor-page-up "no-prefix")
|
||||||
(map-key "CTRL-k" editor-del-row)
|
(map-key "PAGE-DOWN" move-cursor-page-down "no-prefix")
|
||||||
(map-key "CTRL-s" editor-find)
|
(map-key "f" editor-open-file "user")
|
||||||
(map-key "CTRL-r" editor-move-to-end-of-word)
|
(map-key "TAB" editor-insert-tab "no-prefix")
|
||||||
|
(map-key "CTRL-k" editor-del-row "no-prefix")
|
||||||
|
(map-key "CTRL-s" editor-find "no-prefix")
|
||||||
|
(map-key "CTRL-r" editor-move-to-end-of-word "no-prefix")
|
||||||
|
|||||||
@@ -19,6 +19,8 @@ Lisp moveCursorBeginLine(Lisp args, LispError *e, LispContext ctx);
|
|||||||
|
|
||||||
Lisp moveCursorEndLine(Lisp args, LispError *e, LispContext ctx);
|
Lisp moveCursorEndLine(Lisp args, LispError *e, LispContext ctx);
|
||||||
|
|
||||||
|
Lisp l_editorInserTab(Lisp args, LispError *e, LispContext ctx);
|
||||||
|
|
||||||
Lisp deletePreviousChar(Lisp args, LispError *e, LispContext ctx);
|
Lisp deletePreviousChar(Lisp args, LispError *e, LispContext ctx);
|
||||||
|
|
||||||
Lisp editorMoveCursorPageUp(Lisp args, LispError* e, LispContext ctx);
|
Lisp editorMoveCursorPageUp(Lisp args, LispError* e, LispContext ctx);
|
||||||
@@ -37,4 +39,10 @@ Lisp editorFind_L(Lisp args, LispError *e, LispContext ctx);
|
|||||||
|
|
||||||
Lisp editorReadChar_L(Lisp args, LispError *e, LispContext ctx);
|
Lisp editorReadChar_L(Lisp args, LispError *e, LispContext ctx);
|
||||||
|
|
||||||
|
Lisp editorSetPrefix(Lisp args, LispError *e, LispContext ctx);
|
||||||
|
|
||||||
|
Lisp editorPrefix(Lisp args, LispError *e, LispContext ctx);
|
||||||
|
|
||||||
|
void free_structs(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -31,8 +31,14 @@ struct const_t {
|
|||||||
int QUIT_TIMES;
|
int QUIT_TIMES;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct prefix_t {
|
||||||
|
char prefix_name[64];
|
||||||
|
int prefix_id;
|
||||||
|
};
|
||||||
|
|
||||||
struct keyBind_t {
|
struct keyBind_t {
|
||||||
char *key_sequence;
|
char *key_sequence;
|
||||||
|
int prefix_id;
|
||||||
Lisp command;
|
Lisp command;
|
||||||
|
|
||||||
};
|
};
|
||||||
@@ -53,6 +59,7 @@ struct editorConfig {
|
|||||||
int dirty;
|
int dirty;
|
||||||
char *filename;
|
char *filename;
|
||||||
enum editorStatus_e state;
|
enum editorStatus_e state;
|
||||||
|
int prefix_state;
|
||||||
char status_msg[80];
|
char status_msg[80];
|
||||||
time_t status_msg_time;
|
time_t status_msg_time;
|
||||||
struct termios orig_termios; /**< Terminal communication interface */
|
struct termios orig_termios; /**< Terminal communication interface */
|
||||||
@@ -68,6 +75,9 @@ struct editorConfig {
|
|||||||
|
|
||||||
struct keyBind_t* key_binds;
|
struct keyBind_t* key_binds;
|
||||||
int number_of_keybinds;
|
int number_of_keybinds;
|
||||||
|
|
||||||
|
struct prefix_t* prefix;
|
||||||
|
int number_of_prefix;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -24,7 +24,7 @@ char *editorPrompt(char *prompt, char * PlaceHolder, char bPathMode);
|
|||||||
|
|
||||||
char *key_to_string(int key);
|
char *key_to_string(int key);
|
||||||
|
|
||||||
void editorMoveCursor(int key);
|
int editorMoveCursor(int key);
|
||||||
|
|
||||||
int executeKeyBind(char *key_sequence);
|
int executeKeyBind(char *key_sequence);
|
||||||
|
|
||||||
|
|||||||
+12
-12
@@ -1861,8 +1861,8 @@ static Lisp parse_symbol_(Lexer* lex, LispContext ctx)
|
|||||||
char scratch[LISP_IDENTIFIER_MAX];
|
char scratch[LISP_IDENTIFIER_MAX];
|
||||||
size_t length = lexer_copy_token(lex, 0, LISP_IDENTIFIER_MAX, scratch);
|
size_t length = lexer_copy_token(lex, 0, LISP_IDENTIFIER_MAX, scratch);
|
||||||
// always convert symbols to uppercase
|
// always convert symbols to uppercase
|
||||||
for (int i = 0; i < length; ++i)
|
// for (int i = 0; i < length; ++i)
|
||||||
scratch[i] = toupper(scratch[i]);
|
// scratch[i] = toupper(scratch[i]);
|
||||||
return symbol_intern_(ctx.p->symbols, scratch, length, ctx);
|
return symbol_intern_(ctx.p->symbols, scratch, length, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3183,17 +3183,17 @@ LispContext lisp_init(void)
|
|||||||
ctx.p->macros = lisp_make_table(ctx);
|
ctx.p->macros = lisp_make_table(ctx);
|
||||||
|
|
||||||
Lisp* c = ctx.p->symbol_cache;
|
Lisp* c = ctx.p->symbol_cache;
|
||||||
c[SYM_IF] = lisp_make_symbol("IF", ctx);
|
c[SYM_IF] = lisp_make_symbol("if", ctx);
|
||||||
c[SYM_BEGIN] = lisp_make_symbol("BEGIN", ctx);
|
c[SYM_BEGIN] = lisp_make_symbol("begin", ctx);
|
||||||
c[SYM_QUOTE] = lisp_make_symbol("QUOTE", ctx);
|
c[SYM_QUOTE] = lisp_make_symbol("quote", ctx);
|
||||||
c[SYM_QUASI_QUOTE] = lisp_make_symbol("QUASIQUOTE", ctx);
|
c[SYM_QUASI_QUOTE] = lisp_make_symbol("quasiquote", ctx);
|
||||||
c[SYM_UNQUOTE] = lisp_make_symbol("UNQUOTE", ctx);
|
c[SYM_UNQUOTE] = lisp_make_symbol("unquote", ctx);
|
||||||
c[SYM_UNQUOTE_SPLICE] = lisp_make_symbol("UNQUOTESPLICE", ctx);
|
c[SYM_UNQUOTE_SPLICE] = lisp_make_symbol("unquotesplice", ctx);
|
||||||
c[SYM_DEFINE] = lisp_make_symbol("_DEF", ctx);
|
c[SYM_DEFINE] = lisp_make_symbol("_def", ctx);
|
||||||
c[SYM_DEFINE_MACRO] = lisp_make_symbol("DEFINE-MACRO", ctx);
|
c[SYM_DEFINE_MACRO] = lisp_make_symbol("define-macro", ctx);
|
||||||
c[SYM_SET] = lisp_make_symbol("_SET!", ctx);
|
c[SYM_SET] = lisp_make_symbol("_set!", ctx);
|
||||||
c[SYM_LAMBDA] = lisp_make_symbol("/\\_", ctx);
|
c[SYM_LAMBDA] = lisp_make_symbol("/\\_", ctx);
|
||||||
c[SYM_CONS] = lisp_make_symbol("CONS", ctx);
|
c[SYM_CONS] = lisp_make_symbol("cons", ctx);
|
||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+200
-203
@@ -36,7 +36,7 @@ static const char* lib_0_sequences_src_ =
|
|||||||
(if (pair? args) \n\
|
(if (pair? args) \n\
|
||||||
(if (pair? (cdr args)) \n\
|
(if (pair? (cdr args)) \n\
|
||||||
(if (pair? (cdr (cdr args))) \n\
|
(if (pair? (cdr (cdr args))) \n\
|
||||||
`(/\\_ ,(car args) ,(cons 'BEGIN (cdr args))) \n\
|
`(/\\_ ,(car args) ,(cons 'begin (cdr args))) \n\
|
||||||
`(/\\_ ,(car args) ,(car (cdr args)))) \n\
|
`(/\\_ ,(car args) ,(car (cdr args)))) \n\
|
||||||
(syntax-error \"lambda missing body expressions: (lambda (args) body)\")) \n\
|
(syntax-error \"lambda missing body expressions: (lambda (args) body)\")) \n\
|
||||||
(syntax-error \"lambda missing argument: (lambda (args) body)\")))) \n\
|
(syntax-error \"lambda missing argument: (lambda (args) body)\")))) \n\
|
||||||
@@ -44,18 +44,18 @@ static const char* lib_0_sequences_src_ =
|
|||||||
(define-macro set! (lambda (var x) \n\
|
(define-macro set! (lambda (var x) \n\
|
||||||
(begin \n\
|
(begin \n\
|
||||||
(if (not (symbol? var)) (syntax-error \"set! not a variable\")) \n\
|
(if (not (symbol? var)) (syntax-error \"set! not a variable\")) \n\
|
||||||
`(_SET! ,var ,x)))) \n\
|
`(_set! ,var ,x)))) \n\
|
||||||
\n\
|
\n\
|
||||||
(define-macro define \n\
|
(define-macro define \n\
|
||||||
(lambda (var . exprs) \n\
|
(lambda (var . exprs) \n\
|
||||||
(if (symbol? var) \n\
|
(if (symbol? var) \n\
|
||||||
(if (pair? (cdr exprs)) \n\
|
(if (pair? (cdr exprs)) \n\
|
||||||
(syntax-error \"define: (define var x)\") \n\
|
(syntax-error \"define: (define var x)\") \n\
|
||||||
`(_DEF ,var ,(car exprs))) \n\
|
`(_def ,var ,(car exprs))) \n\
|
||||||
(if (pair? var) \n\
|
(if (pair? var) \n\
|
||||||
`(_DEF ,(car var) \n\
|
`(_def ,(car var) \n\
|
||||||
(LAMBDA ,(cdr var) \n\
|
(lambda ,(cdr var) \n\
|
||||||
,(if (null? (cdr exprs)) (car exprs) (cons 'BEGIN exprs)))) \n\
|
,(if (null? (cdr exprs)) (car exprs) (cons 'begin exprs)))) \n\
|
||||||
(syntax-error \"define: not a symbol\") )))) \n\
|
(syntax-error \"define: not a symbol\") )))) \n\
|
||||||
\n\
|
\n\
|
||||||
(define (first x) (car x)) \n\
|
(define (first x) (car x)) \n\
|
||||||
@@ -98,13 +98,13 @@ static const char* lib_0_sequences_src_ =
|
|||||||
(define (_expand-shorthand-body path) \n\
|
(define (_expand-shorthand-body path) \n\
|
||||||
(if (null? path) (cons 'pair '()) \n\
|
(if (null? path) (cons 'pair '()) \n\
|
||||||
(list (if (char=? (car path) #\\A) \n\
|
(list (if (char=? (car path) #\\A) \n\
|
||||||
(cons 'CAR (_expand-shorthand-body (cdr path))))))) \n\
|
(cons 'car (_expand-shorthand-body (cdr path))))))) \n\
|
||||||
\n\
|
\n\
|
||||||
(define (_expand-shorthand text) \n\
|
(define (_expand-shorthand text) \n\
|
||||||
(cons 'DEFINE (cons (list (string->symbol (string-append \"C\" text \"R\")) 'pair) \n\
|
(cons 'define (cons (list (string->symbol (string-append \"C\" text \"R\")) 'pair) \n\
|
||||||
(_expand-shorthand-body (string->list text))))) \n\
|
(_expand-shorthand-body (string->list text))))) \n\
|
||||||
\n\
|
\n\
|
||||||
(define-macro _shorthand-accessors (lambda args (cons 'BEGIN (map1 _expand-shorthand args)))) \n\
|
(define-macro _shorthand-accessors (lambda args (cons 'begin (map1 _expand-shorthand args)))) \n\
|
||||||
\n\
|
\n\
|
||||||
(define (vector . args) (list->vector args)) \n\
|
(define (vector . args) (list->vector args)) \n\
|
||||||
\n\
|
\n\
|
||||||
@@ -124,14 +124,14 @@ static const char* lib_0_sequences_src_ =
|
|||||||
|
|
||||||
static const char* lib_1_forms_src_ =
|
static const char* lib_1_forms_src_ =
|
||||||
"(define (_make-lambda args body) \n\
|
"(define (_make-lambda args body) \n\
|
||||||
(list 'LAMBDA args (if (null? (cdr body)) (car body) (cons 'BEGIN body)))) \n\
|
(list 'lambda args (if (null? (cdr body)) (car body) (cons 'begin body)))) \n\
|
||||||
\n\
|
\n\
|
||||||
\n\
|
\n\
|
||||||
; (LET <name> ((<var0> <expr0>) ... (<varN> <expr1>)) <body0> ... <bodyN>) \n\
|
; (let <name> ((<var0> <expr0>) ... (<varN> <expr1>)) <body0> ... <bodyN>) \n\
|
||||||
; => ((LAMBDA (<var0> ... <varN>) (BEGIN <body0> ... <bodyN>)) <expr0> ... <expr1>) \n\
|
; => ((lambda (<var0> ... <varN>) (begin <body0> ... <bodyN>)) <expr0> ... <expr1>) \n\
|
||||||
; => named \n\
|
; => named \n\
|
||||||
; ((lambda () \n\
|
; ((lambda () \n\
|
||||||
; (define <name> (LAMBDA (<var0> ... <varN>) (BEGIN <body0> ... <bodyN>))) \n\
|
; (define <name> (lambda (<var0> ... <varN>) (begin <body0> ... <bodyN>))) \n\
|
||||||
; (<name> <expr0> ... <exprN>))) \n\
|
; (<name> <expr0> ... <exprN>))) \n\
|
||||||
\n\
|
\n\
|
||||||
(define (_check-binding-list bindings) \n\
|
(define (_check-binding-list bindings) \n\
|
||||||
@@ -145,7 +145,7 @@ static const char* lib_1_forms_src_ =
|
|||||||
(define initial-args (map1 (lambda (entry) (second entry)) bindings)) \n\
|
(define initial-args (map1 (lambda (entry) (second entry)) bindings)) \n\
|
||||||
(if (null? var) \n\
|
(if (null? var) \n\
|
||||||
(cons body-func initial-args) \n\
|
(cons body-func initial-args) \n\
|
||||||
(list (_make-lambda '() (list (list 'DEFINE var body-func) (cons var initial-args)))))) \n\
|
(list (_make-lambda '() (list (list 'define var body-func) (cons var initial-args)))))) \n\
|
||||||
\n\
|
\n\
|
||||||
(define-macro let (lambda args \n\
|
(define-macro let (lambda args \n\
|
||||||
(if (pair? (first args)) \n\
|
(if (pair? (first args)) \n\
|
||||||
@@ -153,8 +153,8 @@ static const char* lib_1_forms_src_ =
|
|||||||
(_let->combination (first args) (second args) (cdr (cdr args)))))) \n\
|
(_let->combination (first args) (second args) (cdr (cdr args)))))) \n\
|
||||||
\n\
|
\n\
|
||||||
(define (_let*-helper bindings body) \n\
|
(define (_let*-helper bindings body) \n\
|
||||||
(if (null? bindings) (if (null? (cdr body)) (car body) (cons 'BEGIN body)) \n\
|
(if (null? bindings) (if (null? (cdr body)) (car body) (cons 'begin body)) \n\
|
||||||
(list 'LET (list (car bindings)) (_let*-helper (cdr bindings) body)))) \n\
|
(list 'let (list (car bindings)) (_let*-helper (cdr bindings) body)))) \n\
|
||||||
\n\
|
\n\
|
||||||
(define-macro let* (lambda (bindings . body) \n\
|
(define-macro let* (lambda (bindings . body) \n\
|
||||||
(_check-binding-list bindings) \n\
|
(_check-binding-list bindings) \n\
|
||||||
@@ -163,17 +163,17 @@ static const char* lib_1_forms_src_ =
|
|||||||
(define-macro letrec (lambda (bindings . body) \n\
|
(define-macro letrec (lambda (bindings . body) \n\
|
||||||
(_check-binding-list bindings) \n\
|
(_check-binding-list bindings) \n\
|
||||||
(cons (_make-lambda (map1 (lambda (entry) (first entry)) bindings) \n\
|
(cons (_make-lambda (map1 (lambda (entry) (first entry)) bindings) \n\
|
||||||
(append (map1 (lambda (entry) (list 'SET! (first entry) (second entry))) \n\
|
(append (map1 (lambda (entry) (list 'set! (first entry) (second entry))) \n\
|
||||||
bindings) body)) \n\
|
bindings) body)) \n\
|
||||||
(map1 (lambda (entry) '()) bindings)))) \n\
|
(map1 (lambda (entry) '()) bindings)))) \n\
|
||||||
\n\
|
\n\
|
||||||
\n\
|
\n\
|
||||||
; (COND (<pred0> <expr0>) \n\
|
; (cond (<pred0> <expr0>) \n\
|
||||||
; (<pred1> <expr1>) \n\
|
; (<pred1> <expr1>) \n\
|
||||||
; ... \n\
|
; ... \n\
|
||||||
; (else <expr-1>)) \n\
|
; (else <expr-1>)) \n\
|
||||||
; => \n\
|
; => \n\
|
||||||
; (IF <pred0> <expr0> \n\
|
; (if <pred0> <expr0> \n\
|
||||||
; (if <pred1> <expr1> \n\
|
; (if <pred1> <expr1> \n\
|
||||||
; .... \n\
|
; .... \n\
|
||||||
; (if <predN> <exprN> <expr-1>)) ... ) \n\
|
; (if <predN> <exprN> <expr-1>)) ... ) \n\
|
||||||
@@ -187,11 +187,11 @@ static const char* lib_1_forms_src_ =
|
|||||||
\n\
|
\n\
|
||||||
(define (_cond-helper clauses) \n\
|
(define (_cond-helper clauses) \n\
|
||||||
(if (null? clauses) '() \n\
|
(if (null? clauses) '() \n\
|
||||||
(if (eq? (car (car clauses)) 'ELSE) \n\
|
(if (eq? (car (car clauses)) 'else) \n\
|
||||||
(cons 'BEGIN (cdr (car clauses))) \n\
|
(cons 'begin (cdr (car clauses))) \n\
|
||||||
(list 'IF \n\
|
(list 'if \n\
|
||||||
(car (car clauses)) \n\
|
(car (car clauses)) \n\
|
||||||
(cons 'BEGIN (cdr (car clauses))) \n\
|
(cons 'begin (cdr (car clauses))) \n\
|
||||||
(_cond-helper (cdr clauses)))))) \n\
|
(_cond-helper (cdr clauses)))))) \n\
|
||||||
\n\
|
\n\
|
||||||
(define-macro cond (lambda clauses \n\
|
(define-macro cond (lambda clauses \n\
|
||||||
@@ -206,26 +206,26 @@ static const char* lib_2_forms_src_ =
|
|||||||
(cond ((null? preds) #t) \n\
|
(cond ((null? preds) #t) \n\
|
||||||
((null? (cdr preds)) (car preds)) \n\
|
((null? (cdr preds)) (car preds)) \n\
|
||||||
(else \n\
|
(else \n\
|
||||||
`(IF ,(car preds) ,(_and-helper (cdr preds)) #f)))) \n\
|
`(if ,(car preds) ,(_and-helper (cdr preds)) #f)))) \n\
|
||||||
(define-macro and (lambda preds (_and-helper preds))) \n\
|
(define-macro and (lambda preds (_and-helper preds))) \n\
|
||||||
\n\
|
\n\
|
||||||
(define (_or-helper preds var) \n\
|
(define (_or-helper preds var) \n\
|
||||||
(cond ((null? preds) #f) \n\
|
(cond ((null? preds) #f) \n\
|
||||||
((null? (cdr preds)) (car preds)) \n\
|
((null? (cdr preds)) (car preds)) \n\
|
||||||
(else \n\
|
(else \n\
|
||||||
`(BEGIN (SET! ,var ,(car preds)) \n\
|
`(begin (set! ,var ,(car preds)) \n\
|
||||||
(IF ,var ,var ,(_or-helper (cdr preds) var)))))) \n\
|
(if ,var ,var ,(_or-helper (cdr preds) var)))))) \n\
|
||||||
\n\
|
\n\
|
||||||
(define-macro or (lambda preds \n\
|
(define-macro or (lambda preds \n\
|
||||||
(let ((var (gensym))) \n\
|
(let ((var (gensym))) \n\
|
||||||
`(LET ((,var '())) ,(_or-helper preds var))))) \n\
|
`(let ((,var '())) ,(_or-helper preds var))))) \n\
|
||||||
\n\
|
\n\
|
||||||
(define-macro case (lambda (key . clauses) \n\
|
(define-macro case (lambda (key . clauses) \n\
|
||||||
(let ((expr (gensym))) \n\
|
(let ((expr (gensym))) \n\
|
||||||
`(LET ((,expr ,key)) \n\
|
`(let ((,expr ,key)) \n\
|
||||||
,(cons 'COND (map1 (lambda (entry) \n\
|
,(cons 'cond (map1 (lambda (entry) \n\
|
||||||
(cons (if (pair? (car entry)) \n\
|
(cons (if (pair? (car entry)) \n\
|
||||||
`(MEMV ,expr (quote ,(car entry))) \n\
|
`(memv ,expr (quote ,(car entry))) \n\
|
||||||
(car entry)) \n\
|
(car entry)) \n\
|
||||||
(cdr entry))) clauses)))))) \n\
|
(cdr entry))) clauses)))))) \n\
|
||||||
\n\
|
\n\
|
||||||
@@ -234,23 +234,24 @@ static const char* lib_2_forms_src_ =
|
|||||||
`(begin (set! ,l (cons ,v ,l)) ,l))) \n\
|
`(begin (set! ,l (cons ,v ,l)) ,l))) \n\
|
||||||
\n\
|
\n\
|
||||||
; (DO ((<var0> <init0> <step0>) ...) (<test> <result>) <body>) \n\
|
; (DO ((<var0> <init0> <step0>) ...) (<test> <result>) <body>) \n\
|
||||||
(define-macro do \n\
|
|
||||||
(lambda (vars loop-check . loops) \n\
|
|
||||||
(let ( (names '()) (inits '()) (steps '()) (f (gensym)) ) \n\
|
|
||||||
(for-each1 (lambda (var) \n\
|
|
||||||
(push (car var) names) \n\
|
|
||||||
(set! var (cdr var)) \n\
|
|
||||||
(push (car var) inits) \n\
|
|
||||||
(set! var (cdr var)) \n\
|
|
||||||
(push (car var) steps)) vars) \n\
|
|
||||||
`((LAMBDA () \n\
|
|
||||||
(DEFINE ,f (LAMBDA ,names \n\
|
|
||||||
(IF ,(car loop-check) \n\
|
|
||||||
,(if (pair? (cdr loop-check)) (car (cdr loop-check)) '()) \n\
|
|
||||||
,(cons 'BEGIN (append loops (list (cons f steps)))) ))) \n\
|
|
||||||
,(cons f inits) \n\
|
|
||||||
)) ))) \n\
|
|
||||||
\n\
|
\n\
|
||||||
|
(define-macro do \n\
|
||||||
|
(lambda (vars loop-check . loops) \n\
|
||||||
|
(let ( (names '()) (inits '()) (steps '()) (f (gensym)) ) \n\
|
||||||
|
(for-each1 (lambda (var-spec) \n\
|
||||||
|
(push (car var-spec) names) \n\
|
||||||
|
(push (car (cdr var-spec)) inits) \n\
|
||||||
|
(if (pair? (cdr (cdr var-spec))) \n\
|
||||||
|
(push (car (cdr (cdr var-spec))) steps) \n\
|
||||||
|
(push (car var-spec) steps))) vars) \n\
|
||||||
|
`((lambda () \n\
|
||||||
|
(define ,f (lambda ,names \n\
|
||||||
|
(if ,(car loop-check) \n\
|
||||||
|
,(if (pair? (cdr loop-check)) (car (cdr loop-check)) '()) \n\
|
||||||
|
,(cons 'begin (append loops (list (cons f steps)))) ))) \n\
|
||||||
|
,(cons f inits) \n\
|
||||||
|
)) ))) \n\
|
||||||
|
\n\
|
||||||
(define-macro dotimes \n\
|
(define-macro dotimes \n\
|
||||||
(lambda (form body) \n\
|
(lambda (form body) \n\
|
||||||
(apply (lambda (i n . result) \n\
|
(apply (lambda (i n . result) \n\
|
||||||
@@ -262,18 +263,18 @@ static const char* lib_2_forms_src_ =
|
|||||||
(define-macro swap! \n\
|
(define-macro swap! \n\
|
||||||
(lambda (x y) \n\
|
(lambda (x y) \n\
|
||||||
(let ((temp (gensym))) \n\
|
(let ((temp (gensym))) \n\
|
||||||
`(LET ((,temp ,x)) \n\
|
`(let ((,temp ,x)) \n\
|
||||||
(SET! ,temp ,x) \n\
|
(set! ,temp ,x) \n\
|
||||||
(SET! ,x ,y) \n\
|
(set! ,x ,y) \n\
|
||||||
(SET! ,y ,temp))))) \n\
|
(set! ,y ,temp))))) \n\
|
||||||
\n\
|
\n\
|
||||||
(define-macro inc! ; CL incf \n\
|
(define-macro inc! ; CL incf \n\
|
||||||
(lambda (x) \n\
|
(lambda (x) \n\
|
||||||
`(SET! ,x (+ ,x 1)))) \n\
|
`(set! ,x (+ ,x 1)))) \n\
|
||||||
\n\
|
\n\
|
||||||
(define-macro dec! ; CL decf \n\
|
(define-macro dec! ; CL decf \n\
|
||||||
(lambda (x) \n\
|
(lambda (x) \n\
|
||||||
`(SET! ,x (- ,x 1))))";
|
`(set! ,x (- ,x 1))))";
|
||||||
|
|
||||||
static const char* lib_3_math_src_ =
|
static const char* lib_3_math_src_ =
|
||||||
"(define (number? x) (real? x)) \n\
|
"(define (number? x) (real? x)) \n\
|
||||||
@@ -445,7 +446,7 @@ static const char* lib_4_sequences_src_ =
|
|||||||
|
|
||||||
static const char* lib_5_streams_src_ =
|
static const char* lib_5_streams_src_ =
|
||||||
"(define-macro delay (lambda (expr) \n\
|
"(define-macro delay (lambda (expr) \n\
|
||||||
`(make-promise ,(cons 'LAMBDA \n\
|
`(make-promise ,(cons 'lambda \n\
|
||||||
(cons '() \n\
|
(cons '() \n\
|
||||||
(cons expr '())))))) \n\
|
(cons expr '())))))) \n\
|
||||||
\n\
|
\n\
|
||||||
@@ -1926,182 +1927,178 @@ static Lisp sch_is_cont(Lisp args, LispError* e, LispContext ctx)
|
|||||||
|
|
||||||
static const LispFuncDef lib_cfunc_defs[] = {
|
static const LispFuncDef lib_cfunc_defs[] = {
|
||||||
|
|
||||||
{ "ERROR", sch_error },
|
{ "error", sch_error },
|
||||||
{ "SYNTAX-ERROR", sch_syntax_error },
|
{ "syntax-error", sch_syntax_error },
|
||||||
|
|
||||||
// Output Procedures https://www.gnu.org/software/mit-scheme/documentation/mit-scheme-ref/Output-Procedures.html
|
// Output Procedures
|
||||||
{ "_WRITE", sch_write },
|
{ "_write", sch_write },
|
||||||
{ "_DISPLAY", sch_display },
|
{ "_display", sch_display },
|
||||||
{ "_WRITE-CHAR", sch_write_char },
|
{ "_write-char", sch_write_char },
|
||||||
{ "_FLUSH-OUTPUT-PORT", sch_flush },
|
{ "_flush-output-port", sch_flush },
|
||||||
{ "_READ", sch_read },
|
{ "_read", sch_read },
|
||||||
{ "INPUT-PORT?", sch_is_port_in },
|
{ "input-port?", sch_is_port_in },
|
||||||
{ "OUTPUT-PORT?", sch_is_port_out },
|
{ "output-port?", sch_is_port_out },
|
||||||
{ "OPEN-INPUT-FILE", sch_open_input },
|
{ "open-input-file", sch_open_input },
|
||||||
{ "OPEN-OUTPUT-FILE", sch_open_output },
|
{ "open-output-file", sch_open_output },
|
||||||
{ "CLOSE-INPUT-PORT", sch_port_close },
|
{ "close-input-port", sch_port_close },
|
||||||
{ "CLOSE-OUTPUT-PORT", sch_port_close },
|
{ "close-output-port", sch_port_close },
|
||||||
{ "EOF-OBJECT?", sch_is_eof },
|
{ "eof-object?", sch_is_eof },
|
||||||
|
|
||||||
// Universal Time https://www.gnu.org/software/mit-scheme/documentation/mit-scheme-ref/Universal-Time.html
|
// Universal Time
|
||||||
{ "GET-UNIVERSAL-TIME", sch_univeral_time },
|
{ "get-universal-time", sch_univeral_time },
|
||||||
{ "PRINT-GC-STATISTICS", sch_print_gc_stats },
|
{ "print-gc-statistics", sch_print_gc_stats },
|
||||||
|
|
||||||
{ "MACROEXPAND", sch_macroexpand },
|
{ "macroexpand", sch_macroexpand },
|
||||||
|
|
||||||
// Equivalence Predicates https://www.gnu.org/software/mit-scheme/documentation/mit-scheme-ref/Equivalence-Predicates.html
|
// Equivalence Predicates
|
||||||
{ "EQ?", sch_exact_eq },
|
{ "eq?", sch_exact_eq },
|
||||||
{ "EQV?", sch_equal },
|
{ "eqv?", sch_equal },
|
||||||
{ "EQUAL?", sch_equal_r },
|
{ "equal?", sch_equal_r },
|
||||||
|
|
||||||
// Booleans https://www.gnu.org/software/mit-scheme/documentation/mit-scheme-ref/Booleans.html
|
// Booleans
|
||||||
{ "BOOLEAN?", sch_is_boolean },
|
{ "boolean?", sch_is_boolean },
|
||||||
{ "NOT", sch_not },
|
{ "not", sch_not },
|
||||||
|
|
||||||
// PAIRS
|
// PAIRS
|
||||||
{ "CONS", sch_cons },
|
{ "cons", sch_cons },
|
||||||
{ "CAR", sch_car },
|
{ "car", sch_car },
|
||||||
{ "CDR", sch_cdr },
|
{ "cdr", sch_cdr },
|
||||||
{ "SET-CAR!", sch_set_car },
|
{ "set-car!", sch_set_car },
|
||||||
{ "SET-CDR!", sch_set_cdr },
|
{ "set-cdr!", sch_set_cdr },
|
||||||
{ "NULL?", sch_is_null },
|
{ "null?", sch_is_null },
|
||||||
{ "PAIR?", sch_is_pair },
|
{ "pair?", sch_is_pair },
|
||||||
|
|
||||||
// Lists https://groups.csail.mit.edu/mac/ftpdir/scheme-7.4/doc-html/scheme_8.html
|
// Lists
|
||||||
{ "LIST", sch_list },
|
{ "list", sch_list },
|
||||||
{ "LIST?", sch_is_list },
|
{ "list?", sch_is_list },
|
||||||
{ "MAKE-LIST", sch_make_list },
|
{ "make-list", sch_make_list },
|
||||||
{ "LIST-COPY", sch_list_copy },
|
{ "list-copy", sch_list_copy },
|
||||||
{ "LENGTH", sch_length },
|
{ "length", sch_length },
|
||||||
{ "APPEND", sch_append },
|
{ "append", sch_append },
|
||||||
{ "APPEND-REVERSE!", sch_append_reverse },
|
{ "append-reverse!", sch_append_reverse },
|
||||||
{ "LIST-REF", sch_list_ref },
|
{ "list-ref", sch_list_ref },
|
||||||
{ "NTHCDR", sch_list_advance },
|
{ "nthcdr", sch_list_advance },
|
||||||
|
|
||||||
// Vectors https://groups.csail.mit.edu/mac/ftpdir/scheme-7.4/doc-html/scheme_9.html#SEC82
|
// Vectors
|
||||||
{ "VECTOR?", sch_is_vector },
|
{ "vector?", sch_is_vector },
|
||||||
{ "MAKE-VECTOR", sch_make_vector },
|
{ "make-vector", sch_make_vector },
|
||||||
{ "VECTOR-GROW", sch_vector_grow },
|
{ "vector-grow", sch_vector_grow },
|
||||||
{ "VECTOR-LENGTH", sch_vector_length },
|
{ "vector-length", sch_vector_length },
|
||||||
{ "VECTOR-SET!", sch_vector_set },
|
{ "vector-set!", sch_vector_set },
|
||||||
{ "VECTOR-SWAP!", sch_vector_swap },
|
{ "vector-swap!", sch_vector_swap },
|
||||||
{ "VECTOR-REF", sch_vector_ref },
|
{ "vector-ref", sch_vector_ref },
|
||||||
{ "VECTOR-FILL!", sch_vector_fill },
|
{ "vector-fill!", sch_vector_fill },
|
||||||
{ "VECTOR-ASSQ", sch_vector_assq },
|
{ "vector-assq", sch_vector_assq },
|
||||||
{ "SUBVECTOR", sch_subvector },
|
{ "subvector", sch_subvector },
|
||||||
{ "LIST->VECTOR", sch_list_to_vector },
|
{ "list->vector", sch_list_to_vector },
|
||||||
{ "VECTOR->LIST", sch_vector_to_list },
|
{ "vector->list", sch_vector_to_list },
|
||||||
|
|
||||||
// Strings https://groups.csail.mit.edu/mac/ftpdir/scheme-7.4/doc-html/scheme_7.html#SEC61
|
// Strings
|
||||||
{ "STRING?", sch_is_string },
|
{ "string?", sch_is_string },
|
||||||
{ "MAKE-STRING", sch_make_string },
|
{ "make-string", sch_make_string },
|
||||||
{ "STRING=?", sch_equal_r },
|
{ "string=?", sch_equal_r },
|
||||||
{ "STRING<?", sch_string_less },
|
{ "string<?", sch_string_less },
|
||||||
{ "SUBSTRING", sch_substring },
|
{ "substring", sch_substring },
|
||||||
{ "STRING-NULL?", sch_string_is_null },
|
{ "string-null?", sch_string_is_null },
|
||||||
{ "STRING-LENGTH", sch_string_length },
|
{ "string-length", sch_string_length },
|
||||||
{ "STRING-REF", sch_string_ref },
|
{ "string-ref", sch_string_ref },
|
||||||
{ "STRING-SET!", sch_string_set },
|
{ "string-set!", sch_string_set },
|
||||||
{ "STRING-UPCASE", sch_string_upcase },
|
{ "string-upcase", sch_string_upcase },
|
||||||
{ "STRING-DOWNCASE", sch_string_downcase },
|
{ "string-downcase", sch_string_downcase },
|
||||||
{ "STRING-APPEND", sch_string_append },
|
{ "string-append", sch_string_append },
|
||||||
{ "STRING->LIST", sch_string_to_list },
|
{ "string->list", sch_string_to_list },
|
||||||
{ "LIST->STRING", sch_list_to_string },
|
{ "list->string", sch_list_to_string },
|
||||||
{ "STRING->NUMBER", sch_string_to_number },
|
{ "string->number", sch_string_to_number },
|
||||||
{ "NUMBER->STRING", sch_number_to_string },
|
{ "number->string", sch_number_to_string },
|
||||||
|
|
||||||
// Characters https://www.gnu.org/software/mit-scheme/documentation/mit-scheme-ref/Characters.html#Characters
|
// Characters
|
||||||
{ "CHAR?", sch_is_char },
|
{ "char?", sch_is_char },
|
||||||
{ "CHAR=?", sch_equals },
|
{ "char=?", sch_equals },
|
||||||
{ "CHAR<?", sch_char_less },
|
{ "char<?", sch_char_less },
|
||||||
|
|
||||||
{ "CHAR-UPCASE", sch_char_upcase },
|
{ "char-upcase", sch_char_upcase },
|
||||||
{ "CHAR-DOWNCASE", sch_char_downcase },
|
{ "char-downcase", sch_char_downcase },
|
||||||
{ "CHAR-WHITESPACE?", sch_char_is_white },
|
{ "char-whitespace?", sch_char_is_white },
|
||||||
{ "CHAR-ALPHANUMERIC?", sch_char_is_alphanum },
|
{ "char-alphanumeric?", sch_char_is_alphanum },
|
||||||
{ "CHAR-ALPHABETIC?", sch_char_is_alpha },
|
{ "char-alphabetic?", sch_char_is_alpha },
|
||||||
{ "CHAR-NUMERIC?", sch_char_is_number },
|
{ "char-numeric?", sch_char_is_number },
|
||||||
{ "CHAR->INTEGER", sch_char_to_int },
|
{ "char->integer", sch_char_to_int },
|
||||||
|
|
||||||
// Association Lists https://www.gnu.org/software/mit-scheme/documentation/mit-scheme-ref/Association-Lists.html
|
// Numerical operations
|
||||||
// Numerical operations https://www.gnu.org/software/mit-scheme/documentation/mit-scheme-ref/Numerical-operations.html
|
|
||||||
{ "=", sch_equals },
|
{ "=", sch_equals },
|
||||||
{ "+", sch_add },
|
{ "+", sch_add },
|
||||||
{ "-", sch_sub },
|
{ "-", sch_sub },
|
||||||
{ "*", sch_mult },
|
{ "*", sch_mult },
|
||||||
{ "/", sch_divide },
|
{ "/", sch_divide },
|
||||||
{ "<", sch_less },
|
{ "<", sch_less },
|
||||||
{ "INTEGER?", sch_is_int },
|
{ "integer?", sch_is_int },
|
||||||
{ "EVEN?", sch_is_even },
|
{ "even?", sch_is_even },
|
||||||
{ "REAL?", sch_is_real },
|
{ "real?", sch_is_real },
|
||||||
{ "EXP", sch_exp },
|
{ "exp", sch_exp },
|
||||||
{ "EXPT", sch_power },
|
{ "expt", sch_power },
|
||||||
{ "LOG", sch_log },
|
{ "log", sch_log },
|
||||||
{ "SIN", sch_sin },
|
{ "sin", sch_sin },
|
||||||
{ "COS", sch_cos },
|
{ "cos", sch_cos },
|
||||||
{ "TAN", sch_tan },
|
{ "tan", sch_tan },
|
||||||
{ "ATAN", sch_atan },
|
{ "atan", sch_atan },
|
||||||
{ "SQRT", sch_sqrt },
|
{ "sqrt", sch_sqrt },
|
||||||
{ "ROUND", sch_round },
|
{ "round", sch_round },
|
||||||
{ "FLOOR", sch_floor },
|
{ "floor", sch_floor },
|
||||||
{ "CEILING", sch_ceiling },
|
{ "ceiling", sch_ceiling },
|
||||||
{ "QUOTIENT", sch_quotient },
|
{ "quotient", sch_quotient },
|
||||||
{ "REMAINDER", sch_remainder },
|
{ "remainder", sch_remainder },
|
||||||
{ "MODULO", sch_modulo },
|
{ "modulo", sch_modulo },
|
||||||
{ "ABS", sch_abs },
|
{ "abs", sch_abs },
|
||||||
{ "MAGNITUDE", sch_abs },
|
{ "magnitude", sch_abs },
|
||||||
{ "EXACT?", sch_is_int },
|
{ "exact?", sch_is_int },
|
||||||
{ "EXACT->INEXACT", sch_to_inexact },
|
{ "exact->inexact", sch_to_inexact },
|
||||||
{ "INEXACT->EXACT", sch_to_exact },
|
{ "inexact->exact", sch_to_exact },
|
||||||
|
|
||||||
// Symbols https://www.gnu.org/software/mit-scheme/documentation/mit-scheme-ref/Symbols.html
|
// Symbols
|
||||||
{ "SYMBOL?", sch_is_symbol },
|
{ "symbol?", sch_is_symbol },
|
||||||
{ "SYMBOL<?", sch_symbol_less },
|
{ "symbol<?", sch_symbol_less },
|
||||||
{ "STRING->SYMBOL", sch_string_to_symbol },
|
{ "string->symbol", sch_string_to_symbol },
|
||||||
{ "SYMBOL->STRING", sch_symbol_to_string },
|
{ "symbol->string", sch_symbol_to_string },
|
||||||
{ "GENERATE-UNINTERNED-SYMBOL", sch_gensym },
|
{ "generate-uninterned-symbol", sch_gensym },
|
||||||
{ "GENSYM", sch_gensym },
|
{ "gensym", sch_gensym },
|
||||||
|
|
||||||
// Environments https://groups.csail.mit.edu/mac/ftpdir/scheme-7.4/doc-html/scheme_14.html
|
// Environments
|
||||||
{ "EVAL", sch_eval },
|
{ "eval", sch_eval },
|
||||||
{ "SCHEME-REPORT-ENVIRONMENT", sch_system_env },
|
{ "scheme-report-environment", sch_system_env },
|
||||||
{ "INTERACTION-ENVIRONMENT", sch_user_env },
|
{ "interaction-environment", sch_user_env },
|
||||||
// { "THE-ENVIRONMENT", sch_current_env },
|
|
||||||
|
|
||||||
// Hash Tables https://www.gnu.org/software/mit-scheme/documentation/mit-scheme-ref/Basic-Hash-Table-Operations.html#Basic-Hash-Table-Operations
|
// Hash Tables
|
||||||
{ "HASH-TABLE?", sch_is_table },
|
{ "hash-table?", sch_is_table },
|
||||||
{ "MAKE-HASH-TABLE", sch_table_make },
|
{ "make-hash-table", sch_table_make },
|
||||||
{ "HASH-TABLE-SET!", sch_table_set },
|
{ "hash-table-set!", sch_table_set },
|
||||||
{ "HASH-TABLE-REF", sch_table_get },
|
{ "hash-table-ref", sch_table_get },
|
||||||
{ "HASH-TABLE-SIZE", sch_table_size },
|
{ "hash-table-size", sch_table_size },
|
||||||
{ "HASH-TABLE->ALIST", sch_table_to_alist },
|
{ "hash-table->alist", sch_table_to_alist },
|
||||||
|
|
||||||
{ "PROMISE?", sch_is_promise },
|
{ "promise?", sch_is_promise },
|
||||||
{ "MAKE-PROMISE", sch_make_promise },
|
{ "make-promise", sch_make_promise },
|
||||||
{ "_PROMISE-PROCEDURE", sch_promise_proc },
|
{ "_promise-procedure", sch_promise_proc },
|
||||||
{ "_PROMISE-STORE!", sch_promise_store },
|
{ "_promise-store!", sch_promise_store },
|
||||||
{ "PROMISE-VALUE", sch_promise_val },
|
{ "promise-value", sch_promise_val },
|
||||||
{ "PROMISE-FORCED?", sch_promise_forced },
|
{ "promise-forced?", sch_promise_forced },
|
||||||
|
|
||||||
// Procedures https://www.gnu.org/software/mit-scheme/documentation/mit-scheme-ref/Procedure-Operations.html#Procedure-Operations
|
// Procedures
|
||||||
{ "APPLY", sch_apply },
|
{ "apply", sch_apply },
|
||||||
{ "COMPILED-PROCEDURE?", sch_is_func },
|
{ "compiled-procedure?", sch_is_func },
|
||||||
{ "COMPOUND-PROCEDURE?", sch_is_lambda },
|
{ "compound-procedure?", sch_is_lambda },
|
||||||
{ "PROCEDURE-ENVIRONMENT", sch_lambda_env },
|
{ "procedure-environment", sch_lambda_env },
|
||||||
// TOOD: Almost standard
|
{ "procedure-body", sch_lambda_body },
|
||||||
{ "PROCEDURE-BODY", sch_lambda_body },
|
{ "call/cc", sch_call_cc },
|
||||||
{ "CALL/CC", sch_call_cc },
|
{ "continuation?", sch_is_cont },
|
||||||
{ "CONTINUATION?", sch_is_cont },
|
|
||||||
|
|
||||||
// Random Numbers https://www.gnu.org/software/mit-scheme/documentation/mit-scheme-ref/Random-Numbers.html
|
// Random Numbers
|
||||||
{ "RANDOM", sch_pseudo_rand },
|
{ "random", sch_pseudo_rand },
|
||||||
{ "RANDOM-SEED!", sch_pseudo_seed },
|
{ "random-seed!", sch_pseudo_seed },
|
||||||
|
|
||||||
// Garbage Collection https://www.gnu.org/software/mit-scheme/documentation/mit-scheme-user/Garbage-Collection.html
|
// Garbage Collection
|
||||||
{ "GC-FLIP", sch_gc_flip },
|
{ "gc-flip", sch_gc_flip },
|
||||||
|
|
||||||
{ NULL, NULL }
|
{ NULL, NULL }
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void lisp_lib_load(LispContext ctx)
|
void lisp_lib_load(LispContext ctx)
|
||||||
@@ -2111,14 +2108,14 @@ void lisp_lib_load(LispContext ctx)
|
|||||||
|
|
||||||
lisp_table_set(
|
lisp_table_set(
|
||||||
table,
|
table,
|
||||||
lisp_make_symbol("_CURRENT-OUTPUT-PORT", ctx),
|
lisp_make_symbol("_current-output-port", ctx),
|
||||||
lisp_make_port(stdout, 0),
|
lisp_make_port(stdout, 0),
|
||||||
ctx
|
ctx
|
||||||
);
|
);
|
||||||
|
|
||||||
lisp_table_set(
|
lisp_table_set(
|
||||||
table,
|
table,
|
||||||
lisp_make_symbol("_CURRENT-INPUT-PORT", ctx),
|
lisp_make_symbol("_current-input-port", ctx),
|
||||||
lisp_make_port(stdin, 1),
|
lisp_make_port(stdin, 1),
|
||||||
ctx
|
ctx
|
||||||
);
|
);
|
||||||
|
|||||||
+110
-41
@@ -1,87 +1,127 @@
|
|||||||
#include "../include/builtins.h"
|
#include "../include/builtins.h"
|
||||||
#include "../include/define.h"
|
|
||||||
#include "../include/input.h"
|
|
||||||
#include "../include/file_io.h"
|
|
||||||
#include "../include/editor_op.h"
|
|
||||||
#include "../include/row_op.h"
|
|
||||||
#include "../include/data.h"
|
#include "../include/data.h"
|
||||||
|
#include "../include/define.h"
|
||||||
|
#include "../include/editor_op.h"
|
||||||
|
#include "../include/file_io.h"
|
||||||
|
#include "../include/input.h"
|
||||||
|
#include "../include/row_op.h"
|
||||||
|
#include "include/output.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
struct prefix_t find_prefix(const char prefix_name[64]) {
|
||||||
|
int i = E.number_of_prefix + 1;
|
||||||
|
while (i--) {
|
||||||
|
if (!strcmp(prefix_name, E.prefix[i].prefix_name)) {
|
||||||
|
return E.prefix[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return E.prefix[0];
|
||||||
|
}
|
||||||
|
|
||||||
Lisp mapKey(Lisp args, LispError *e, LispContext ctx) {
|
Lisp mapKey(Lisp args, LispError *e, LispContext ctx) {
|
||||||
|
/*
|
||||||
|
* 3 arguments keybind command prefix
|
||||||
|
*/
|
||||||
const char *key_sequence = lisp_string(lisp_car(args));
|
const char *key_sequence = lisp_string(lisp_car(args));
|
||||||
args = lisp_cdr(args);
|
args = lisp_cdr(args);
|
||||||
// second argument
|
// second argument
|
||||||
Lisp func = lisp_car(args);
|
Lisp func = lisp_car(args);
|
||||||
|
|
||||||
E.key_binds =
|
E.key_binds = (struct keyBind_t *)realloc(
|
||||||
(struct keyBind_t *)realloc(E.key_binds, ++E.number_of_keybinds * sizeof(struct keyBind_t));
|
E.key_binds, ++E.number_of_keybinds * sizeof(struct keyBind_t));
|
||||||
E.key_binds[E.number_of_keybinds - 1].key_sequence = (char *) malloc(50 * sizeof(char));
|
E.key_binds[E.number_of_keybinds - 1].key_sequence =
|
||||||
|
(char *)malloc(50 * sizeof(char));
|
||||||
|
|
||||||
strncpy(E.key_binds[E.number_of_keybinds - 1].key_sequence, key_sequence, 50);
|
strncpy(E.key_binds[E.number_of_keybinds - 1].key_sequence, key_sequence, 50);
|
||||||
|
|
||||||
E.key_binds[E.number_of_keybinds - 1].command = func;
|
E.key_binds[E.number_of_keybinds - 1].command = func;
|
||||||
|
|
||||||
|
// Third argument
|
||||||
|
args = lisp_cdr(args);
|
||||||
|
const char *prefix_name = lisp_string(lisp_car(args));
|
||||||
|
struct prefix_t prefix = find_prefix(prefix_name);
|
||||||
|
|
||||||
|
E.key_binds[E.number_of_keybinds - 1].prefix_id = prefix.prefix_id;
|
||||||
|
|
||||||
return lisp_null();
|
return lisp_null();
|
||||||
}
|
}
|
||||||
|
|
||||||
Lisp moveCursor(Lisp args, LispError *e, LispContext ctx) {
|
Lisp moveCursor(Lisp args, LispError *e, LispContext ctx) {
|
||||||
const char *direction = lisp_string(lisp_car(args));
|
const char *direction = lisp_string(lisp_car(args));
|
||||||
|
int is_in = 0;
|
||||||
switch (direction[0]) {
|
switch (direction[0]) {
|
||||||
case 'u':
|
case 'u':
|
||||||
editorMoveCursor(ARROW_UP);
|
is_in = editorMoveCursor(ARROW_UP);
|
||||||
break;
|
break;
|
||||||
case 'd':
|
case 'd':
|
||||||
editorMoveCursor(ARROW_DOWN);
|
is_in = editorMoveCursor(ARROW_DOWN);
|
||||||
break;
|
break;
|
||||||
case 'r':
|
case 'r':
|
||||||
editorMoveCursor(ARROW_RIGHT);
|
is_in = editorMoveCursor(ARROW_RIGHT);
|
||||||
break;
|
break;
|
||||||
case 'l':
|
case 'l':
|
||||||
editorMoveCursor(ARROW_LEFT);
|
is_in = editorMoveCursor(ARROW_LEFT);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
fprintf(stderr, "move lisp %d\n", is_in);
|
||||||
|
return lisp_make_bool(is_in);
|
||||||
return lisp_null();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Lisp editorQuit(Lisp args, LispError* e, LispContext ctx) {
|
void free_structs(void) {
|
||||||
|
int i;
|
||||||
|
free(E.prefix);
|
||||||
|
for (i = 0; i < E.number_of_keybinds; ++i) {
|
||||||
|
free(E.key_binds[i].key_sequence);
|
||||||
|
}
|
||||||
|
free(E.key_binds);
|
||||||
|
free(E.filename);
|
||||||
|
free(E.row->chars);
|
||||||
|
free(E.row->render);
|
||||||
|
free(E.row);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Lisp editorQuit(Lisp args, LispError *e, LispContext ctx) {
|
||||||
if (E.dirty && E.quit_times_buffer > 0) {
|
if (E.dirty && E.quit_times_buffer > 0) {
|
||||||
editorSetStatusMessage("WARNING! Changes hasn't been saved. Press Ctrl-Q "
|
editorSetStatusMessage("WARNING! Changes hasn't been saved. Press Ctrl-Q "
|
||||||
"another time to quit.");
|
"another time to quit.");
|
||||||
--E.quit_times_buffer;
|
--E.quit_times_buffer;
|
||||||
return lisp_null();
|
return lisp_null();
|
||||||
}
|
}
|
||||||
|
free_structs();
|
||||||
write(STDOUT_FILENO, "\x1b[2J", 4);
|
write(STDOUT_FILENO, "\x1b[2J", 4);
|
||||||
write(STDOUT_FILENO, CURSOR_TOP_LEFT, 3);
|
write(STDOUT_FILENO, CURSOR_TOP_LEFT, 3);
|
||||||
disableRawMode();
|
disableRawMode();
|
||||||
|
lisp_shutdown(E.ctx);
|
||||||
exit(0);
|
exit(0);
|
||||||
|
|
||||||
return lisp_null();
|
return lisp_null();
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Lisp l_editorSave(Lisp args, LispError *e, LispContext ctx) {
|
||||||
Lisp l_editorSave(Lisp args, LispError* e, LispContext ctx) {
|
|
||||||
|
|
||||||
editorSave();
|
editorSave();
|
||||||
|
|
||||||
return lisp_null();
|
|
||||||
|
|
||||||
|
return lisp_null();
|
||||||
}
|
}
|
||||||
|
|
||||||
Lisp l_editorInsertNewLine(Lisp args, LispError* e, LispContext ctx) {
|
Lisp l_editorInsertNewLine(Lisp args, LispError *e, LispContext ctx) {
|
||||||
|
|
||||||
editorInsertNewLine();
|
editorInsertNewLine();
|
||||||
|
|
||||||
return lisp_null();
|
|
||||||
|
|
||||||
|
return lisp_null();
|
||||||
|
}
|
||||||
|
|
||||||
|
Lisp l_editorInserTab(Lisp args, LispError *e, LispContext ctx) {
|
||||||
|
|
||||||
|
for (int i = 0; i<E.constantes.TAB_LENGTH; ++i) {
|
||||||
|
editorInsertChar(' ');
|
||||||
|
}
|
||||||
|
|
||||||
|
return lisp_null();
|
||||||
}
|
}
|
||||||
|
|
||||||
Lisp moveCursorBeginLine(Lisp args, LispError *e, LispContext ctx) {
|
Lisp moveCursorBeginLine(Lisp args, LispError *e, LispContext ctx) {
|
||||||
@@ -89,20 +129,19 @@ Lisp moveCursorBeginLine(Lisp args, LispError *e, LispContext ctx) {
|
|||||||
return lisp_null();
|
return lisp_null();
|
||||||
}
|
}
|
||||||
|
|
||||||
Lisp moveCursorEndLine(Lisp args, LispError* e, LispContext ctx) {
|
Lisp moveCursorEndLine(Lisp args, LispError *e, LispContext ctx) {
|
||||||
if (E.cursor_y < E.numrows) {
|
if (E.cursor_y < E.numrows) {
|
||||||
E.cursor_x = E.row[E.cursor_y].size;
|
E.cursor_x = E.row[E.cursor_y].size;
|
||||||
}
|
}
|
||||||
return lisp_null();
|
return lisp_null();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Lisp deletePreviousChar(Lisp args, LispError *e, LispContext ctx) {
|
||||||
Lisp deletePreviousChar(Lisp args, LispError* e, LispContext ctx) {
|
|
||||||
editorDelChar();
|
editorDelChar();
|
||||||
return lisp_null();
|
return lisp_null();
|
||||||
}
|
}
|
||||||
|
|
||||||
Lisp editorMoveCursorPageUp(Lisp args, LispError* e, LispContext ctx) {
|
Lisp editorMoveCursorPageUp(Lisp args, LispError *e, LispContext ctx) {
|
||||||
E.cursor_y = E.row_offset;
|
E.cursor_y = E.row_offset;
|
||||||
int times = E.screenrows;
|
int times = E.screenrows;
|
||||||
while (--times) {
|
while (--times) {
|
||||||
@@ -111,7 +150,7 @@ Lisp editorMoveCursorPageUp(Lisp args, LispError* e, LispContext ctx) {
|
|||||||
return lisp_null();
|
return lisp_null();
|
||||||
}
|
}
|
||||||
|
|
||||||
Lisp editorMoveCursorPageDown(Lisp args, LispError* e, LispContext ctx) {
|
Lisp editorMoveCursorPageDown(Lisp args, LispError *e, LispContext ctx) {
|
||||||
E.cursor_y = E.row_offset + E.screenrows - 1;
|
E.cursor_y = E.row_offset + E.screenrows - 1;
|
||||||
if (E.cursor_y > E.numrows) {
|
if (E.cursor_y > E.numrows) {
|
||||||
E.cursor_y = E.numrows;
|
E.cursor_y = E.numrows;
|
||||||
@@ -126,13 +165,15 @@ Lisp editorMoveCursorPageDown(Lisp args, LispError* e, LispContext ctx) {
|
|||||||
|
|
||||||
Lisp editorOpenFile(Lisp args, LispError *e, LispContext ctx) {
|
Lisp editorOpenFile(Lisp args, LispError *e, LispContext ctx) {
|
||||||
char *filename = editorPrompt("Open : %s", getenv("PWD"), 1);
|
char *filename = editorPrompt("Open : %s", getenv("PWD"), 1);
|
||||||
if (filename)
|
if (filename){
|
||||||
editorOpen(filename);
|
editorOpen(filename);
|
||||||
|
}
|
||||||
|
free(filename);
|
||||||
|
|
||||||
|
|
||||||
return lisp_null();
|
return lisp_null();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Lisp editorPrintC(Lisp args, LispError *e, LispContext ctx) {
|
Lisp editorPrintC(Lisp args, LispError *e, LispContext ctx) {
|
||||||
char c = lisp_string(lisp_car(args))[0];
|
char c = lisp_string(lisp_car(args))[0];
|
||||||
editorInsertChar(c);
|
editorInsertChar(c);
|
||||||
@@ -141,20 +182,21 @@ Lisp editorPrintC(Lisp args, LispError *e, LispContext ctx) {
|
|||||||
|
|
||||||
Lisp addPackage(Lisp args, LispError *e, LispContext ctx) {
|
Lisp addPackage(Lisp args, LispError *e, LispContext ctx) {
|
||||||
const char *package_name = lisp_string(lisp_car(args));
|
const char *package_name = lisp_string(lisp_car(args));
|
||||||
char *package_dir = (char *) calloc(256, sizeof(char));
|
fprintf(stderr, "%s\n", package_name);
|
||||||
|
char *package_dir = (char *)calloc(256, sizeof(char));
|
||||||
FILE *fd_package = NULL;
|
FILE *fd_package = NULL;
|
||||||
strcat(package_dir, getenv("HOME"));
|
strcat(package_dir, getenv("HOME"));
|
||||||
strcat(package_dir, "/.beluga/packages/");
|
strcat(package_dir, "/.beluga/packages/");
|
||||||
strcat(package_dir, package_name);
|
strcat(package_dir, package_name);
|
||||||
strcat(package_dir, "/init.lisp");
|
strcat(package_dir, "/init.lisp");
|
||||||
|
fprintf(stderr, "%s\n", package_dir);
|
||||||
fd_package = fopen(package_dir, "r");
|
fd_package = fopen(package_dir, "r");
|
||||||
lisp_eval(lisp_read_file(fd_package, &E.ctx_error, E.ctx), &E.ctx_error,
|
lisp_eval(lisp_read_file(fd_package, &E.ctx_error, E.ctx), &E.ctx_error,
|
||||||
E.ctx);
|
E.ctx);
|
||||||
fclose(fd_package);
|
fclose(fd_package);
|
||||||
free(package_dir);
|
free(package_dir);
|
||||||
|
|
||||||
return lisp_null();
|
return lisp_null();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Lisp editorDelRow_L(Lisp args, LispError *e, LispContext ctx) {
|
Lisp editorDelRow_L(Lisp args, LispError *e, LispContext ctx) {
|
||||||
@@ -163,12 +205,39 @@ Lisp editorDelRow_L(Lisp args, LispError *e, LispContext ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Lisp editorFind_L(Lisp args, LispError *e, LispContext ctx) {
|
Lisp editorFind_L(Lisp args, LispError *e, LispContext ctx) {
|
||||||
editorFind();
|
editorFind();
|
||||||
return lisp_null();
|
return lisp_null();
|
||||||
}
|
}
|
||||||
|
|
||||||
Lisp editorReadChar_L(Lisp args, LispError *e, LispContext ctx) {
|
Lisp editorReadChar_L(Lisp args, LispError *e, LispContext ctx) {
|
||||||
fprintf(stderr, "char read : %c\n", E.row[E.cursor_y].render[E.cursor_x]);
|
Lisp returned_char;
|
||||||
return lisp_make_char(E.row[E.cursor_y].render[E.cursor_x]);
|
if (E.row[E.cursor_y].render[E.cursor_x] == 0) {
|
||||||
|
returned_char = lisp_make_char('a');
|
||||||
|
} else {
|
||||||
|
|
||||||
|
returned_char = lisp_make_char(E.row[E.cursor_y].render[E.cursor_x]);
|
||||||
|
}
|
||||||
|
return returned_char;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Lisp editorSetPrefix(Lisp args, LispError *e, LispContext ctx) {
|
||||||
|
/*
|
||||||
|
* Set the prefix state of editor to the prefix in argument
|
||||||
|
*/
|
||||||
|
const char *prefix_name = lisp_string(lisp_car(args));
|
||||||
|
struct prefix_t prefix = find_prefix(prefix_name);
|
||||||
|
E.prefix_state = prefix.prefix_id;
|
||||||
|
editorSetStatusMessage("prefix %s", prefix.prefix_name);
|
||||||
|
fprintf(stderr, "%s set\n", prefix_name);
|
||||||
|
|
||||||
|
return lisp_null();
|
||||||
|
}
|
||||||
|
|
||||||
|
Lisp editorPrefix(Lisp args, LispError *e, LispContext ctx) {
|
||||||
|
E.prefix = (struct prefix_t *)realloc(E.prefix, (++(E.number_of_prefix) + 1) *
|
||||||
|
sizeof(struct prefix_t));
|
||||||
|
E.prefix[E.number_of_prefix].prefix_id = E.number_of_prefix;
|
||||||
|
strncpy(E.prefix[E.number_of_prefix].prefix_name, lisp_string(lisp_car(args)),
|
||||||
|
64);
|
||||||
|
return lisp_null();
|
||||||
|
}
|
||||||
|
|||||||
@@ -13,6 +13,10 @@ void editorInsertChar(int c) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void editorInsertNewLine() {
|
void editorInsertNewLine() {
|
||||||
|
/*
|
||||||
|
* Add new line and place the cursor at the beginning of it
|
||||||
|
*/
|
||||||
|
fprintf(stderr, "Inserting new line\n");
|
||||||
erow *row;
|
erow *row;
|
||||||
if (!E.cursor_x) {
|
if (!E.cursor_x) {
|
||||||
editorInsertRow(E.cursor_y, "", 0);
|
editorInsertRow(E.cursor_y, "", 0);
|
||||||
@@ -27,6 +31,7 @@ void editorInsertNewLine() {
|
|||||||
}
|
}
|
||||||
++E.cursor_y;
|
++E.cursor_y;
|
||||||
E.cursor_x = 0;
|
E.cursor_x = 0;
|
||||||
|
fprintf(stderr, "Insert new line done\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void editorDelChar() {
|
void editorDelChar() {
|
||||||
|
|||||||
+30
-21
@@ -1,8 +1,9 @@
|
|||||||
#include "../include/init.h"
|
#include "../include/init.h"
|
||||||
|
#include "../include/builtins.h"
|
||||||
#include "../include/data.h"
|
#include "../include/data.h"
|
||||||
#include "../include/terminal.h"
|
#include "../include/terminal.h"
|
||||||
#include "../include/builtins.h"
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
#define LISP_IMPLEMENTATION
|
#define LISP_IMPLEMENTATION
|
||||||
#include "../include/lisp.h"
|
#include "../include/lisp.h"
|
||||||
@@ -10,35 +11,36 @@
|
|||||||
|
|
||||||
extern struct editorConfig;
|
extern struct editorConfig;
|
||||||
|
|
||||||
|
|
||||||
void registerBuiltin(char *key_sequence, LispCFunc f) {
|
void registerBuiltin(char *key_sequence, LispCFunc f) {
|
||||||
lisp_env_define(E.ctx.p->env, lisp_make_symbol(key_sequence, E.ctx),
|
lisp_env_define(E.ctx.p->env, lisp_make_symbol(key_sequence, E.ctx),
|
||||||
lisp_make_func(f), E.ctx);
|
lisp_make_func(f), E.ctx);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void initBuiltins() {
|
void initBuiltins() {
|
||||||
// move cursor
|
// move cursor
|
||||||
registerBuiltin("MOVE-CURSOR", moveCursor);
|
registerBuiltin("move-cursor", moveCursor);
|
||||||
registerBuiltin("MAP-KEY", mapKey);
|
registerBuiltin("map-key", mapKey);
|
||||||
registerBuiltin("EDITOR-QUIT", editorQuit);
|
registerBuiltin("editor-quit", editorQuit);
|
||||||
registerBuiltin("EDITOR-SAVE", l_editorSave);
|
registerBuiltin("editor-save", l_editorSave);
|
||||||
registerBuiltin("EDITOR-INSERT-NEW-LINE", l_editorInsertNewLine);
|
registerBuiltin("editor-insert-new-line", l_editorInsertNewLine);
|
||||||
registerBuiltin("MOVE-CURSOR-BEG-LINE", moveCursorBeginLine);
|
registerBuiltin("move-cursor-beg-line", moveCursorBeginLine);
|
||||||
registerBuiltin("MOVE-CURSOR-END-LINE", moveCursorEndLine);
|
registerBuiltin("move-cursor-end-line", moveCursorEndLine);
|
||||||
registerBuiltin("EDITOR-DELETE-PREVIOUS-CHAR", deletePreviousChar);
|
registerBuiltin("editor-delete-previous-char", deletePreviousChar);
|
||||||
registerBuiltin("MOVE-CURSOR-PAGE-UP", editorMoveCursorPageUp);
|
registerBuiltin("move-cursor-page-up", editorMoveCursorPageUp);
|
||||||
registerBuiltin("MOVE-CURSOR-PAGE-DOWN", editorMoveCursorPageDown);
|
registerBuiltin("move-cursor-page-down", editorMoveCursorPageDown);
|
||||||
registerBuiltin("EDITOR-OPEN-FILE", editorOpenFile);
|
registerBuiltin("editor-open-file", editorOpenFile);
|
||||||
registerBuiltin("EDITOR-INSERT-CHAR", editorPrintC);
|
registerBuiltin("editor-insert-char", editorPrintC);
|
||||||
registerBuiltin("ADD-PACKAGE", addPackage);
|
registerBuiltin("add-package", addPackage);
|
||||||
registerBuiltin("EDITOR-DEL-ROW", editorDelRow_L);
|
registerBuiltin("editor-del-row", editorDelRow_L);
|
||||||
registerBuiltin("EDITOR-FIND", editorFind_L);
|
registerBuiltin("editor-find", editorFind_L);
|
||||||
registerBuiltin("EDITOR-READ-CHAR", editorReadChar_L);
|
registerBuiltin("editor-read-char", editorReadChar_L);
|
||||||
|
registerBuiltin("add-prefix", editorPrefix);
|
||||||
|
registerBuiltin("editor-set-prefix", editorSetPrefix);
|
||||||
|
registerBuiltin("editor-insert-tab", l_editorInserTab);
|
||||||
}
|
}
|
||||||
|
|
||||||
void initEditor() {
|
void initEditor() {
|
||||||
char * init_file_path = (char *) calloc(256, sizeof(char));
|
char *init_file_path = (char *)calloc(256, sizeof(char));
|
||||||
E.cursor_x = 0;
|
E.cursor_x = 0;
|
||||||
E.cursor_y = 0;
|
E.cursor_y = 0;
|
||||||
E.rx = 0;
|
E.rx = 0;
|
||||||
@@ -57,6 +59,13 @@ void initEditor() {
|
|||||||
E.screenrows -= 2;
|
E.screenrows -= 2;
|
||||||
|
|
||||||
E.number_of_keybinds = 0;
|
E.number_of_keybinds = 0;
|
||||||
|
E.number_of_prefix = 0;
|
||||||
|
// General prefix is 0 (no prefix)
|
||||||
|
E.prefix = (struct prefix_t *)malloc(sizeof(struct prefix_t));
|
||||||
|
E.prefix[0].prefix_id = 0;
|
||||||
|
strncpy(E.prefix[0].prefix_name, "no-prefix", 64);
|
||||||
|
|
||||||
|
E.prefix_state = 0;
|
||||||
|
|
||||||
strcat(init_file_path, getenv("HOME"));
|
strcat(init_file_path, getenv("HOME"));
|
||||||
strcat(init_file_path, "/.beluga/config/init.lisp");
|
strcat(init_file_path, "/.beluga/config/init.lisp");
|
||||||
@@ -75,7 +84,7 @@ void initEditor() {
|
|||||||
die("init failed");
|
die("init failed");
|
||||||
}
|
}
|
||||||
lisp_eval(E.ctx_data, &E.ctx_error, E.ctx);
|
lisp_eval(E.ctx_data, &E.ctx_error, E.ctx);
|
||||||
|
|
||||||
// To modify
|
// To modify
|
||||||
|
|
||||||
E.constantes.TAB_LENGTH =
|
E.constantes.TAB_LENGTH =
|
||||||
|
|||||||
+78
-74
@@ -1,84 +1,82 @@
|
|||||||
#include "../include/input.h"
|
#include "../include/input.h"
|
||||||
|
#include "../include/define.h"
|
||||||
#include "../include/editor_op.h"
|
#include "../include/editor_op.h"
|
||||||
#include "../include/output.h"
|
#include "../include/output.h"
|
||||||
#include "../include/define.h"
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
extern struct editorConfig E;
|
extern struct editorConfig E;
|
||||||
|
|
||||||
char * file_completion(const char *path) {
|
char *file_completion(const char *path) {
|
||||||
DIR * dir;
|
DIR *dir;
|
||||||
struct dirent *entry;
|
struct dirent *entry;
|
||||||
char directory[128];
|
char directory[128];
|
||||||
char predict[128];
|
char predict[128];
|
||||||
int predict_len = 0;
|
int predict_len = 0;
|
||||||
|
|
||||||
if (path[strlen(path) - 1] == '/') {
|
if (path[strlen(path) - 1] == '/') {
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find dir name
|
// Find dir name
|
||||||
char * last_slash = strrchr(path, '/');
|
char *last_slash = strrchr(path, '/');
|
||||||
if (last_slash) {
|
if (last_slash) {
|
||||||
size_t dir_len = last_slash - path + 1; // length of dir_path
|
size_t dir_len = last_slash - path + 1; // length of dir_path
|
||||||
strncpy(directory, path, dir_len);
|
strncpy(directory, path, dir_len);
|
||||||
predict_len = strlen(path) - dir_len - 1;
|
predict_len = strlen(path) - dir_len - 1;
|
||||||
strncpy(predict, last_slash + 1, predict_len);
|
strncpy(predict, last_slash + 1, predict_len);
|
||||||
directory[dir_len] = '\0';
|
directory[dir_len] = '\0';
|
||||||
predict[predict_len] = '\0';
|
predict[predict_len] = '\0';
|
||||||
fprintf(stderr, "%s %s\n", directory, predict);
|
fprintf(stderr, "%s %s\n", directory, predict);
|
||||||
} else {
|
} else {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
dir = opendir(directory);
|
dir = opendir(directory);
|
||||||
if (!dir)
|
if (!dir)
|
||||||
return NULL;
|
|
||||||
|
|
||||||
while ((entry = readdir(dir)) != NULL) {
|
|
||||||
if (strncmp(entry->d_name, predict, predict_len) == 0) {
|
|
||||||
static char full_path[128];
|
|
||||||
snprintf(full_path, sizeof(full_path), "%s%s", directory, entry->d_name);
|
|
||||||
|
|
||||||
struct stat st;
|
|
||||||
if (stat(full_path, &st) == 0 && S_ISDIR(st.st_mode)) {
|
|
||||||
strcat(full_path, "/"); // add slash for directories
|
|
||||||
}
|
|
||||||
|
|
||||||
return strdup(full_path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cleanup when no more entries
|
|
||||||
closedir(dir);
|
|
||||||
dir = NULL;
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
while ((entry = readdir(dir)) != NULL) {
|
||||||
|
if (strncmp(entry->d_name, predict, predict_len) == 0) {
|
||||||
|
static char full_path[128];
|
||||||
|
snprintf(full_path, sizeof(full_path), "%s%s", directory, entry->d_name);
|
||||||
|
|
||||||
|
struct stat st;
|
||||||
|
if (stat(full_path, &st) == 0 && S_ISDIR(st.st_mode)) {
|
||||||
|
strcat(full_path, "/"); // add slash for directories
|
||||||
|
}
|
||||||
|
|
||||||
|
return strdup(full_path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cleanup when no more entries
|
||||||
|
closedir(dir);
|
||||||
|
dir = NULL;
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \fn char * editorPrompt(struct editorConfig *E, char *prompt, char bPathMode)
|
* \fn char * editorPrompt(struct editorConfig *E, char *prompt, char bPathMode)
|
||||||
* \brief Return user input in a prompt when enter is hit. */
|
* \brief Return user input in a prompt when enter is hit. */
|
||||||
|
|
||||||
char *editorPrompt(char *prompt, char * placeHolder, char bPathMode) {
|
char *editorPrompt(char *prompt, char *placeHolder, char bPathMode) {
|
||||||
size_t buf_size = 128;
|
size_t buf_size = 128;
|
||||||
char *buf = malloc(buf_size);
|
char *buf = malloc(buf_size);
|
||||||
size_t buf_len = 0;
|
size_t buf_len = 0;
|
||||||
int c = 0;
|
int c = 0;
|
||||||
buf[0] = '\0';
|
buf[0] = '\0';
|
||||||
strcpy(buf, placeHolder);
|
strcpy(buf, placeHolder);
|
||||||
buf_len = strlen(placeHolder);
|
buf_len = strlen(placeHolder);
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
editorSetStatusMessage(prompt, buf);
|
editorSetStatusMessage(prompt, buf);
|
||||||
editorRefreshScreen();
|
editorRefreshScreen();
|
||||||
c = editorReadKey();
|
c = editorReadKey();
|
||||||
if (c == DEL_KEY || c == CTRL_KEY('h') || c == BACKSPACE) {
|
if (c == DEL_KEY || c == CTRL_KEY('h') || c == BACKSPACE) {
|
||||||
@@ -95,23 +93,23 @@ char *editorPrompt(char *prompt, char * placeHolder, char bPathMode) {
|
|||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
} else if (bPathMode && c == '\t') {
|
} else if (bPathMode && c == '\t') {
|
||||||
char path[128];
|
char path[128];
|
||||||
char * pwd;
|
char *pwd;
|
||||||
if (buf[0] != '/') {
|
if (buf[0] != '/') {
|
||||||
pwd = getenv("PWD");
|
pwd = getenv("PWD");
|
||||||
fprintf(stderr, "%s\n", pwd);
|
fprintf(stderr, "%s\n", pwd);
|
||||||
memcpy(path, pwd, strlen(pwd));
|
memcpy(path, pwd, strlen(pwd));
|
||||||
path[strlen(pwd)] = '/';
|
path[strlen(pwd)] = '/';
|
||||||
strncat(path, buf, buf_len);
|
strncat(path, buf, buf_len);
|
||||||
} else {
|
} else {
|
||||||
strcpy(path, buf);
|
strcpy(path, buf);
|
||||||
}
|
}
|
||||||
memset(buf, 0, 128);
|
memset(buf, 0, 128);
|
||||||
buf_len = 0;
|
buf_len = 0;
|
||||||
strcpy(buf, file_completion(path));
|
strcpy(buf, file_completion(path));
|
||||||
buf_len = strlen(buf);
|
buf_len = strlen(buf);
|
||||||
buf[buf_len] = '\0';
|
buf[buf_len] = '\0';
|
||||||
|
|
||||||
} else if (!iscntrl(c) && c < 128) {
|
} else if (!iscntrl(c) && c < 128) {
|
||||||
if (buf_len == buf_size - 1) {
|
if (buf_len == buf_size - 1) {
|
||||||
buf_size *= 2;
|
buf_size *= 2;
|
||||||
@@ -129,11 +127,12 @@ char *key_to_string(int key) {
|
|||||||
char tmp[10];
|
char tmp[10];
|
||||||
sprintf(tmp, "%d", key);
|
sprintf(tmp, "%d", key);
|
||||||
|
|
||||||
|
|
||||||
// First test enter key
|
// First test enter key
|
||||||
|
|
||||||
if (key == '\r') {
|
if (key == '\r') {
|
||||||
strcpy(key_str, "ENTER");
|
strcpy(key_str, "ENTER");
|
||||||
|
} else if (key == '\t') {
|
||||||
|
strcpy(key_str, "TAB");
|
||||||
} else if (key >= 1 && key <= 26) { // CTRL keys
|
} else if (key >= 1 && key <= 26) { // CTRL keys
|
||||||
snprintf(key_str, sizeof(key_str), "CTRL-%c", 'a' + key - 1);
|
snprintf(key_str, sizeof(key_str), "CTRL-%c", 'a' + key - 1);
|
||||||
} else {
|
} else {
|
||||||
@@ -158,9 +157,8 @@ char *key_to_string(int key) {
|
|||||||
strcpy(key_str, "PAGE-DOWN");
|
strcpy(key_str, "PAGE-DOWN");
|
||||||
break;
|
break;
|
||||||
case DEL_KEY:
|
case DEL_KEY:
|
||||||
fprintf(stderr, "delete key\n");
|
|
||||||
strcpy(key_str, "DEL");
|
strcpy(key_str, "DEL");
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case BACKSPACE:
|
case BACKSPACE:
|
||||||
strcpy(key_str, "BACKSPACE");
|
strcpy(key_str, "BACKSPACE");
|
||||||
@@ -189,8 +187,7 @@ char *key_to_string(int key) {
|
|||||||
return key_str;
|
return key_str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int editorMoveCursor(int key) {
|
||||||
void editorMoveCursor(int key) {
|
|
||||||
erow *row = (E.cursor_y >= E.numrows) ? NULL : &E.row[E.cursor_y];
|
erow *row = (E.cursor_y >= E.numrows) ? NULL : &E.row[E.cursor_y];
|
||||||
int row_len;
|
int row_len;
|
||||||
switch (key) {
|
switch (key) {
|
||||||
@@ -226,19 +223,27 @@ void editorMoveCursor(int key) {
|
|||||||
row_len = row ? row->size : 0;
|
row_len = row ? row->size : 0;
|
||||||
if (E.cursor_x > row_len) {
|
if (E.cursor_x > row_len) {
|
||||||
E.cursor_x = row_len;
|
E.cursor_x = row_len;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int executeKeyBind(char *key_sequence) {
|
int executeKeyBind(char *key_sequence) {
|
||||||
int i;
|
int i;
|
||||||
|
int previous_state = 0;
|
||||||
|
fprintf(stderr, "pressed %s\n", key_sequence);
|
||||||
for (i = 0; i < E.number_of_keybinds; ++i) {
|
for (i = 0; i < E.number_of_keybinds; ++i) {
|
||||||
if (!strcmp(key_sequence, E.key_binds[i].key_sequence)) {
|
if (!strcmp(key_sequence, E.key_binds[i].key_sequence)) {
|
||||||
|
if (E.prefix_state != E.key_binds[i].prefix_id) {
|
||||||
fprintf(stderr, "lisp function %s\n", key_sequence);
|
return 0;
|
||||||
// It's a symbol, create a function call
|
}
|
||||||
lisp_eval(lisp_cons(E.key_binds[i].command, lisp_null(), E.ctx),
|
previous_state = E.prefix_state;
|
||||||
&E.ctx_error, E.ctx);
|
// It's a symbol, create a function call
|
||||||
return 1;
|
lisp_eval(lisp_cons(E.key_binds[i].command, lisp_null(), E.ctx),
|
||||||
|
&E.ctx_error, E.ctx);
|
||||||
|
if (E.prefix_state == previous_state)
|
||||||
|
E.prefix_state = 0;
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@@ -252,5 +257,4 @@ void editorProcessKeypress() {
|
|||||||
}
|
}
|
||||||
editorInsertChar(c);
|
editorInsertChar(c);
|
||||||
E.quit_times_buffer = E.constantes.QUIT_TIMES;
|
E.quit_times_buffer = E.constantes.QUIT_TIMES;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user