diff --git a/CHANGELOG.md b/CHANGELOG.md index a3cb1b69c..ef50b0876 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,7 @@ * fix reading local files in browser [#276](https://github.com/jcubic/lips/issues/276) * fix parsing invalid expression `(1 . 2 3)` [#245](https://github.com/jcubic/lips/issues/245) * fix invalid error message for not matched `syntax-rules` [#243](https://github.com/jcubic/lips/issues/243) +* fix silent error when class don't have parent [#272](https://github.com/jcubic/lips/issues/272) ## 1.0.0-beta.17 ### Breaking diff --git a/dist/std.min.scm b/dist/std.min.scm index e6e4f79f2..8348dee46 100644 --- a/dist/std.min.scm +++ b/dist/std.min.scm @@ -64,6 +64,7 @@ (define binary (%doc "(binary fn)\u000A\u000AReturns a new function with arguments limited to two." (curry n-ary 2))) (define (%class-lambda expr) "(class-lambda expr)\u000A\u000AReturns a lambda expression where input expression lambda have `this` as first argument." (let ((args (gensym (quote args)))) (quasiquote (lambda (unquote args) (apply (unquote (cadr expr)) this (unquote args)))))) (define (%class-method-name expr) "(%class-method-name expr)\u000A\u000AHelper function that allows to use [Symbol.asyncIterator] inside method name." (if (pair? expr) (car expr) (list (quote quote) expr))) +(define (constructor) "(constructor)\u000A\u000AFunction that is present in JavaScript environment. We define it in Scheme\u000Ato fix an issue with define-class. This function throw an error." (throw (new Error "Invalid call to constructor function"))) (define-macro (define-class name parent . body) "(define-class name parent . body)\u000A\u000ADefines a class - JavaScript function constructor with prototype.\u000A\u000Ausage:\u000A\u000A (define-class Person Object\u000A (constructor (lambda (self name)\u000A (set-obj! self '_name name)))\u000A (hi (lambda (self)\u000A (display (string-append self._name \" says hi\"))\u000A (newline))))\u000A (define jack (new Person \"Jack\"))\u000A (jack.hi) ; prints \"Jack says hi\"" (let iter ((functions (quote ())) (constructor (quote ())) (lst body)) (if (null? lst) (quasiquote (begin (define (unquote name) (unquote (if (null? constructor) (quasiquote (lambda ())) (append (%class-lambda constructor) (list (quote this)))))) (set-obj! (unquote name) (Symbol.for "__class__") #t) (unquote (if (not (null? parent)) (quasiquote (begin (set-obj! (unquote name) (quote prototype) (Object.create (. (unquote parent) (quote prototype)))) (set-obj! (. (unquote name) (quote prototype)) (quote constructor) (unquote name)))))) (set-obj! (unquote name) (quote __name__) (quote (unquote name))) (unquote-splicing (map (lambda (fn) (quasiquote (set-obj! (. (unquote name) (quote prototype)) (unquote (%class-method-name (car fn))) (unquote (%class-lambda fn))))) functions)))) (let ((item (car lst))) (if (eq? (car item) (quote constructor)) (iter functions item (cdr lst)) (iter (cons item functions) constructor (cdr lst))))))) (define-syntax class (syntax-rules () ((_) (error "class: parent required")) ((_ parent body ...) (let () (define-class temp parent body ...) temp))) "(class body ...)\u000A\u000AAllows to create anonymous classes. See define-class for details.") (define (make-tags expr) "(make-tags expression)\u000A\u000AReturns a list structure of code with better syntax then raw LIPS" (quasiquote (h (unquote (let ((val (car expr))) (if (key? val) (key->string val) val))) (alist->object ((unquote (quote quasiquote)) (unquote (pair-map (lambda (car cdr) (quasiquote ((unquote (key->string car)) (unquote (quote unquote)) (unquote cdr)))) (cadr expr))))) (unquote (if (not (null? (cddr expr))) (if (and (pair? (caddr expr)) (let ((s (caaddr expr))) (and (symbol? s) (eq? s (quote list))))) (quasiquote (list->array (list (unquote-splicing (map make-tags (cdaddr expr)))))) (caddr expr))))))) diff --git a/dist/std.scm b/dist/std.scm index 983bfadba..bbce8c8a4 100644 --- a/dist/std.scm +++ b/dist/std.scm @@ -862,6 +862,14 @@ (car expr) (list 'quote expr))) +;; ----------------------------------------------------------------------------- +(define (constructor) + "(constructor) + + Function that is present in JavaScript environment. We define it in Scheme + to fix an issue with define-class. This function throw an error." + (throw (new Error "Invalid call to constructor function"))) + ;; ----------------------------------------------------------------------------- (define-macro (define-class name parent . body) "(define-class name parent . body) diff --git a/dist/std.xcb b/dist/std.xcb index eabfc5f61..1d0417962 100644 Binary files a/dist/std.xcb and b/dist/std.xcb differ diff --git a/lib/bootstrap.scm b/lib/bootstrap.scm index 0ac041d46..1a2fbe8e9 100755 --- a/lib/bootstrap.scm +++ b/lib/bootstrap.scm @@ -862,6 +862,14 @@ (car expr) (list 'quote expr))) +;; ----------------------------------------------------------------------------- +(define (constructor) + "(constructor) + + Function that is present in JavaScript environment. We define it in Scheme + to fix an issue with define-class. This function throw an error." + (throw (new Error "Invalid call to constructor function"))) + ;; ----------------------------------------------------------------------------- (define-macro (define-class name parent . body) "(define-class name parent . body)