/* Copyright 2022 Benjamin Vedder benjamin@vedder.se This file is part of the VESC firmware. The VESC firmware is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. The VESC firmware is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "lispif.h" #include "lispbm.h" static const char* functions[] = { "(defun uart-read-bytes (buffer n ofs)" "(let ((rd (uart-read buffer n ofs)))" "(if (num-eq rd n)" "(bufset-u8 buffer 0 (+ ofs rd))" "(progn (yield 4000) (uart-read-bytes buffer (- n rd) (+ ofs rd)))" ")))", "(defun uart-read-until (buffer n ofs end)" "(let ((rd (uart-read buffer n ofs end)))" "(if (and (> rd 0) (or (num-eq rd n) (num-eq (bufget-u8 buffer (+ ofs (- rd 1))) end)))" "(bufset-u8 buffer 0 (+ ofs rd))" "(progn (yield 10000) (uart-read-until buffer (- n rd) (+ ofs rd) end))" ")))", "(defun map (f lst)" "(if (= lst nil) nil " "(cons (f (car lst)) (map f (cdr lst)))))", "(defun iota (n)" "(let ((iacc (lambda (acc i)" "(if (< i 0) acc (iacc (cons i acc) (- i 1))))))" "(iacc nil n)))", "(defun range (start end)" "(map (lambda (x) (+ x start)) (iota (- end start))))", "(defun foldl (f init lst)" "(if (= lst nil) init (foldl f (f init (car lst)) (cdr lst))))", "(defun foldr (f init lst)" "(if (= lst nil) init (f (car lst) (foldr f init (cdr lst)))))", "(defun reverse (lst)" "(let ((revacc (lambda (acc lst)" "(if (= nil lst) acc (revacc (cons (car lst) acc) (cdr lst))))))" "(revacc nil lst)))", "(defun length (lst)" "(let ((len (lambda (l lst)" "(if (= lst nil) l (len (+ l 1) (cdr lst))))))" "(len 0 lst)))", "(defun apply (f lst) (eval `(,f ,@lst)))", "(defun zipwith (f x y)" "(let ((map-rec (lambda (f res lst ys)" "(if (= lst nil)" "(reverse res)" "(map-rec f (cons (f (car lst) (car ys)) res) (cdr lst) (cdr ys))))))" "(map-rec f nil x y)))", "(defun sleep (seconds) (yield (* seconds 1000000)))", "(defun filter (f lst)" "(let ((filter-rec (lambda (f lst ys)" "(if (= lst nil)" "(reverse ys)" "(if (f (car lst))" "(filter-rec f (cdr lst) (cons (car lst) ys))" "(filter-rec f (cdr lst) ys))))))" "(filter-rec f lst nil)" "))", "(defun str-len (str) (- (buflen str) 1))", "(defun sort (f lst)" "(let ((insert (lambda (elt f sorted-lst)" "(if (= sorted-lst nil) (list elt)" "(if (f elt (car sorted-lst)) (cons elt sorted-lst)" "(cons (car sorted-lst) (insert elt f (cdr sorted-lst))))))))" "(if (= lst nil) nil (insert (car lst) f (sort f (cdr lst))))))", "(defun str-cmp-asc (a b) (< (str-cmp a b) 0))", "(defun str-cmp-dsc (a b) (> (str-cmp a b) 0))", }; static const char* macros[] = { "(define defun (macro (name args body) `(define ,name (lambda ,args ,body))))", }; static bool strmatch(const char *str1, const char *str2) { unsigned int len = strlen(str1); if (str2[len] != ' ') { return false; } bool same = true; for (unsigned int i = 0;i < len;i++) { if (str1[i] != str2[i]) { same = false; break; } } return same; } bool lispif_vesc_dynamic_loader(const char *str, const char **code) { for (unsigned int i = 0; i < (sizeof(macros) / sizeof(macros[0]));i++) { if (strmatch(str, macros[i] + 8)) { *code = macros[i]; return true; } } for (unsigned int i = 0; i < (sizeof(functions) / sizeof(functions[0]));i++) { if (strmatch(str, functions[i] + 7)) { *code = functions[i]; return true; } } return false; }