Git Product home page Git Product logo

fe's People

Contributors

rxi avatar timgates42 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

fe's Issues

68k runtime issue

$ fe scripts/life.fe 
>> iteration 1 
(- # -) 
(- # -) 
(- # -) 
>> iteration 2 
(- - -) 
(# # #) 
(- - -) 
>> iteration 3 
(- # -) 
(- # -) 
(- # -) 
>> iteration 4 
(- - -) 
(# # #) 
(- - -) 
error: dotted pair in argument list 
=> (nth x (nth y grid)) 
=> (or (nth x (nth y grid)) 0) 
=> (get-cell grid (- x 1) y) 
=> (+ (get-cell grid (- x 1) (- y 1)) (get-cell grid (- x 1) y) (g 
=> (let n (+ (get-cell grid (- x 1) (- y 1)) (get-cell grid (- x 1 
=> (next-cell grid cell x y) 
=> (f (car lst)) 
=> (cons (f (car lst)) res) 
=> (= res (cons (f (car lst)) res)) 
=> (while lst (= res (cons (f (car lst)) res)) (= lst (cdr lst))) 
=> (map (fn (cell) (= x (+ x 1)) (next-cell grid cell x y)) row) 
=> (f (car lst)) 
=> (cons (f (car lst)) res) 
=> (= res (cons (f (car lst)) res)) 
=> (while lst (= res (cons (f (car lst)) res)) (= lst (cdr lst))) 
=> (map (fn (row) (= y (+ y 1)) (let x -1) (map (fn (cell) (= x (+ 
=> (next-grid grid) 
=> (= grid (next-grid grid)) 
=> (while (<= i n) (print ">> iteration" i) (print-grid grid) (pri 

how to make an eval function?

Thanks for fe -- a very nice tiny interpreter.

How could I make an eval function (or macro)? i.e. such that

(= a '(+ 1 2))
(eval a) => 3

I tried using mac and fn but couldn't make it. Did I miss something obvious?

Minor warning

SAS/C Amiga Compiler 6.58
Copyright (c) 1988-1995 SAS Institute Inc.

====================
  return (chr = fgetc(udata)) ==  (-1)  ? '\0' : chr;
fe.c 550 Warning 85: return value mismatch for function "readfp"
                     Expecting "char", found "int"
Slink - Version 6.58
Copyright (c) 1988-1995 SAS Institute, Inc.  All Rights Reserved.


SLINK Complete - Maximum code size = 89848 ($00015ef8) bytes

Final output file size = 27496 ($00006b68) bytes

How do you propose to use `mark` and `gc` of the `fe_Handlers` structure?

The FE_TPTR has no extra data to recognize how this should be marked (with fe_handlers(ctx)->mark) or released (with fe_handlers(ctx)->gc). In most cases, you need to change the data structure of data in ptr to recognize it from handlers. Why not add handlers directly to the FE_TPTR type?

What about `gensym`?

The gensym function can be very useful in macros. It can be effectively implemented by creating symbols that are not added to symlist, so such symbols can be removed by the garbage collector and may not have a string representation.
This is how you can change the implementation of the for macro from 'scripts/macros.fe' using gensym:

(= for (mac (item lst . body)
  (let for-iter (gensym))
  (list 'do
    (list 'let for-iter lst)
    (list 'while for-iter
      (list 'let item (list 'car for-iter))
      (list '= for-iter (list 'cdr for-iter))
      (cons 'do body)
    )
  )
))

It is assumed that for-iter should not be visible when body is called. I'm implemented it in my fork.

`fe_write()` crashes on circular lists

This problem can be solved by marking all pairs (just like garbage collection) before printing, and unmarking them afterwards. If marked object was found during printing, you should output something like .... But this will slow down fe_write() twice.

`is` is sometimes incorrect because `==` does not work for floating-point comparison in C

Thanks for publishing fe! It's very cool. Turning on more compiler warnings (I enjoy strange hobbies) I found this:

// src/fe.c:203:49: warning: comparing floating point with == or != is unsafe [-Wfloat-equal]
//  if (type(a) == FE_TNUMBER) { return number(a) == number(b); }
//                                      ~~~~~~~~~ ^  ~~~~~~~~~

I found that it is indeed a practical problem in the REPL: I have 2 expressions that print equal but for which is returns nil (correctly).

> (= x (/ 10.2 3))
nil
> x
3.4
> (= y (/ 30.6 9))
nil
> y
3.4
> (is x y)
nil

I propose 2 possible fixes in the C file below:

// src/fe.c:203:49: warning: comparing floating point with == or != is unsafe [-Wfloat-equal]
//  if (type(a) == FE_TNUMBER) { return number(a) == number(b); }
//                                      ~~~~~~~~~ ^  ~~~~~~~~~
//
// You can see with Python 3 that there is a tiny bit of floating point error:
//
// >>> 10.2 / 3
// 3.4
// >>> 30.6 / 9
// 3.4000000000000004
// >>> 3 * 3.4
// 10.2
// >>> 9 * 3.4
// 30.599999999999998
// >>> (10.2 / 3) == (30.6 / 9)
// False
//
// In Python, we can deal with this using `math.isclose`.
//
// fe prints them the same (format string `%.7g`), but does equality on their
// bitwise representations. So you end up with an error you can't see in the
// REPL, nor fix using library functions.
//
// % ./fe
// > (= x (/ 10.2 3))
// nil
// > x
// 3.4
// > (= y (/ 30.6 9))
// nil
// > y
// 3.4
// > (is x y)
// nil
//
// Changing fe to use `%.7f` at least makes the error visible in the REPL. I see
// 2 paths to solving this: (1) provide `isclose` (`double_nearly_equal` in the
// C below) in the standard library; or (2) make `is` use `double_nearly_equal`
// for number objects. With either option, using `%.7f` might also help people
// see the issue.

#include <float.h>
#include <math.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>

#define MIN(a, b) ((a) < (b) ? (a) : (b))

// Translated from [the original
// Java](https://floating-point-gui.de/errors/comparison/). If you want to use
// `float`, use `fabsf` and `FLT_*`. If you want to use `long double`, use
// `fabsl` and `LDBL_*`.
//
// See also
// https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/.
static bool double_nearly_equal(double a, double b, double epsilon) {
  const double absA = fabs(a);
  const double absB = fabs(b);
  const double diff = fabs(a - b);
// It's OK to turn this warning off for this limited section of code, because
// it's in the context of handling tiny errors.
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wfloat-equal"
  if (a == b) {
    // Special case; handles infinities.
    return true;
  } else if (a == 0 || b == 0 || (absA + absB < DBL_MIN)) {
#pragma clang diagnostic pop
    // Either a or b is zero, or both are extremely close to it. Relative error
    // is less meaningful here.
    return diff < (epsilon * DBL_MIN);
  }
  // Use relative error.
  return diff / MIN((absA + absB), DBL_MAX) < epsilon;
}

int main(int count, char* arguments[]) {
  if (count != 5) {
    fprintf(stderr, "Usage: ./float_nearly_equal 10.2 3 30.6 9\n");
    return -1;
  }

  const double a = strtod(arguments[1], NULL);
  const double b = strtod(arguments[2], NULL);
  const double c = strtod(arguments[3], NULL);
  const double d = strtod(arguments[4], NULL);
  const double r1 = a / b;
  const double r2 = c / d;
  printf("%.20f / %.20f (%.20f) == %.20f / %.20f (%.20f) : %d\n", a, b, r1, c, d, r2, r1 == r2);
  printf("%.20f / %.20f double_nearly_equal %.20f / %.20f : %d\n", a, b, c, d,
         double_nearly_equal(a / b, c / d, DBL_EPSILON));
}

Completely black window

Whenever I attempt to run any of the scripts provided in fe/scripts using cel7 the window turns completely black, I am not sure if it's an issue in the files or if I am missing any requirements I did not know about, everything except the no input file error returns a black screen, I have tried to run it through the command line but it gives the same result.

Is there any way to solve this? I am using Windows 11 if OS is relevant

Check amount of passed arguments

how would I check the amount of arguments the user passed to a function, or at least check if there's an argument after the current one? I wanna make a function with 4 optional arguments

no-op in eval: P_FN/P_MAC

In the P_FN and P_MAC case of eval, we set va to a newly allocated object containing (env . arg).
Afterwards, we call fe_nextarg, discarding the return value and advancing the arg-list, which contains the argument list of the funtion and the expression itself.
But the previous value of arg was already baked into va, and arg is not used anywhere later in eval (and is local to it).

Therefore, is the fe_nextarg line a no-op?
https://github.com/rxi/fe/blob/master/src/fe.c#L660

Recompilation with the call removed does not seem to change the behaviour of function declaration.

Making it a tutorial?

I went through all of your repositories after searching for how to get OOP in lua and found your very well-written repository on that topic. I really like your overall projects style and your choices.

I recently came across this tool for making tutorial like that, and I just finished studying this tutorial and I learnt ALOT, and was thinking to myself it would be very good if I could do something like that, and then I went through this repo.

I would like to make a tutorial for this repository, what do you think?

Strange behavior with macro expanding

For example (is nil ((mac () nil))) returns nil, although the macro expands to nil and this should be equivalent to (is nil nil).

The problem is that when the macro is evaluated, the value of the original form is replaced by the result of the macro expansion and create new nil object.

Implementing OOP (Structs or objects) for fe

Hi @rxi !
I'm so interested in fe and liked it so much, However...
I didn't found any example/way about implementing Object-Oriented stuff for fe!

I tried to implement struct via this way:

(do
  ; Value from list by index
  (= nth (fn (n lst)
    (while (< 0 n)
      (= n (- n 1))
      (= lst (cdr lst)))
    (if (is n 0) (car lst))
  ))
  
  ; Trick to make Structs ;)
  ; Create list storing cons(s), Like structs in C
  (= obj (list
    (cons "A" 1)
    (cons "B" 2)
    (cons "C" 3)
    (cons "D" 4)
  ))
  
  ; Get struct prop (Remember that list works like array)
  (print (car (nth 3 obj)))
  (print (cdr (nth 3 obj)))
  
  (if (is (car (nth 3 obj)) "D")
    (print "STRUCTS IMPLEMENTATION WORKED!")
  )
)

But i think this gets much difficult to get property of struct, Is there some way in C/fe to implement OOP stuff?

Thanks!

'let': no recursive functions

What is a lisp without recursion? Not very useful.
Therefore it is a pity that with fe you cannot specify a recursive function, using 'let'. You are forced to use '=', but then the function gets global scope which is not always wanted.
Maybe there is a small modification possible to solve this problem?

Handling user input?

Firstly, I fully confess that I'm totally inept when it comes to writing C, so the answer here may very well to be to extend fe -- but I'm wondering about the best way to pass user input into a program written in fe -- either by pipe or by prompting for user input.

Motivation, minimalism, live AST

Looking at your repositories I feel like someone still understands the meaning of minimalism, KISS and overall the art of programming. Kudos!

I'd like to ask few things as I'm overly curious about your motivation, background etc.

  1. Do you use fe in real projects or do you know about other projects using fe?

  2. What was the motivation to create fe if you already made aria?

  3. (somewhat related to (2)) Have you considered implementing a different programming paradigm than Lisp-like?
    For embedded languages I personally like the "live AST" paradigm (any computation is a manipulation of AST - i.e. homomorphism like in Lisp, but a bit less cluttered ๐Ÿ˜‰) used e.g. in TCL/Rebol/Red/Spry languages (Spry being my favorite).

Add a Makefile?

Hi!

Mostly just writing this issue to say how freaking cool this project is. Readable code, good docs, permissible license. Looking forward to exploring the C API a bit. I'd be very curious to learn about your motivations for building fe, and if you use it inside of any other projects.

Oh yeah, right... erm, the issue. Have you ever considered adding a tiny top-level Makefile?
It would be nice to be able to build things with "make", clean things with "make clean", and install with "sudo make install". It would only be a small addition to the project, but it would provide a build system that is both consistent and familiar.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.