~brenns10/funlisp

8c9f9aca795b29b3c0cd0dab7b571b782e1c227b — Stephen Brennan 1 year, 8 months ago 12f19a6
Fix bug in macro argument evaluation
3 files changed, 27 insertions(+), 2 deletions(-)

M CHANGELOG.md
A scripts/tests/macros.lisp
M src/types.c
M CHANGELOG.md => CHANGELOG.md +6 -0
@@ 9,6 9,12 @@ project will use [Semantic Versioning](https://semver.org) for non-beta releases
changes may be made on minor version bumps, and feature additions / bug-fixes
will be made on patch versions.

## Unreleased
### Fixed
- `macro` construct was incorrectly evaluating its arguments prior to execution.
  This change is breaking, but since it reflects major incorrect behavior, it
  will be released in a minor version bump.

## [1.1.0] - 2018-08-22

### Added

A scripts/tests/macros.lisp => scripts/tests/macros.lisp +13 -0
@@ 0,0 1,13 @@
; Create the "defun" and "defmacro" constructs and use them
(define defun (macro (name args code) `(define ,name (lambda ,args ,code))))
(define defmacro (macro (name args code) `(define ,name (macro ,args ,code))))
(defun add5 (x) (+ 5 x))
(assert (= (add5 5) 10))

; Test that the code from macros is evaluated in the correct scope
(defmacro setvalue (name value) `(define ,name ,value))
(define test 3)
(setvalue test 5)
(assert (= test 5))

; OUTPUT(0)

M src/types.c => src/types.c +8 -2
@@ 648,8 648,14 @@ static lisp_value *lambda_call(lisp_runtime *rt, lisp_scope *scope,
	lisp_scope *inner;
	lisp_value *result;

	argvalues = lisp_eval_list(rt, scope, arguments);
	lisp_error_check(argvalues);
	if (lambda->lambda_type == TP_MACRO) {
		/* macros receive their arguments un-evaluated */
		argvalues = arguments;
	} else {
		/* lambdas evaluate their arguments */
		argvalues = lisp_eval_list(rt, scope, arguments);
		lisp_error_check(argvalues);
	}

	if (lisp_is_bad_list(argvalues)) {
		return lisp_error(rt, LE_SYNTAX, "unexpected cons cell");