Menu

Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Show posts Menu

Topics - Dmi

#41
Anything else we might add? / put-url Segfault
June 05, 2006, 06:40:16 AM
Initially, I got this with real apache and put.cgi from newLisp manual.

The following - is the protoclo recreation, modelled with netcat.


dmi@stone$ newlisp
newLISP v.8.8.8 on linux, execute 'newlisp -h' for more info.

> (put-url "http://www.test.ru:8080/in/test1" "test-1n")
Segmentation fault


The other side protocol is following:
fortuna:sites-available# nc -l -p 8080
PUT /in/test1 HTTP/1.1
Host: www.test.ru
User-Agent: newLISP v8808
Connection: close
Content-type: text/html
Content-length: 7

test-1
HTTP/1.1 200 OK
Date: Mon, 05 Jun 2006 13:30:25 GMT
Server: Apache/2.0.54 (Debian GNU/Linux) mod_python/3.1.3 Python/2.3.5 PHP/4.3.10-16 mod_perl/1.999.21 Perl/v5.8.4
Connection: close
Transfer-Encoding: chunked
Content-Type: text/html

0


The string "HTTP/1.1 200 OK" and the rest is the answer to the client, pasted through a netcat connection.
#42
newLISP and the O.S. / locale and filenames
May 23, 2006, 11:45:19 PM
(read-file "some-name-with-national-characters") wan't read the file :-(



In MSWin I have two russian encodings (Russian_Russia.1251 and Russian_Russia.866), I tried to (set-locale ...) with both (with success result), but read-file returns nil either.
#43
Hi, Lutz!



I like an idea to use some non-alpha prefixes for some of my symbols.

For example '%name to represent an index of something data in a record-like list, so I then can use (lst %name) instead of (lst 5) etc.



According to continous development of newlisp, is there ones, which can be used safely, not conflicting to future syntax improvements?
#44
Hi, Lutz!



Looking into rickiboy's comma-expand (and also into a few similar my own functions) I got an opinion, that it would be nice to have a hard-coded function for recursive tree iteration.



The main problems with such algorithms written in newlisp are:

1. Effective coding of tree-walk in newlisp needs two functions - external - as a dynamic variables holder and internal for recursive walk. When written, looks pretty ugly :-

2. The (if (list? item) (recursive-call item)) construct causes a multiple copying of a tested sublist (for passing as an argument). So for a list of depth of 10, each 10th-level element will be copied 10 times, each 9th-level sublist will be copied 9 times and so on. This makes the algorithm _incredible_ slow for a large deep lists.



Hardcoded version may behave like this:

(do-recursive (sym-val sym-pos sym-len sym-type lst) body)

that will behave like a dolist but

- the body is evaluated only for non-list items and for empty list items.

- sym-val is for a value (as in dolist)

- sym-pos is for current position in list tree (like for push and ref)

- sym-len is a length of a currently iterated sublist

- sym-type gets values '(), '(lambda) and '(lambda-macro) - empty ones - that will reflect the type of a sub-list, which item is currently processed.

Note, that in a body:

(= 0 (pos -1)) will reflect the beginning of a list.

(= sym-len (- (pos -1) 1) will reflect the last item of a sublist (but, probably, there could be another way)

Also It would be _very_ cool (imho) to have an ability in a body to "skip" a requested number of next items in a current sublist.



....something like this :-)
#45
Anything else we might add? / protecting macro
May 01, 2006, 05:08:24 AM
Lutz,

Is it a good trick to define a macro as a context default function?

Seems that this can protect internal macro's symbols from interferring with ones that will be passed into macro:
(context 'push-end)
(set 'push-end
  (lambda-macro (_l_push _lst_push)
    "(push-end item list) - push item to the end of the list"
    (eval (list 'push (quote (eval _l_push)) _lst_push -1))))
(context MAIN)
;===================
> (push-end (list 2 3) _lst_push)
(2 3)
> _lst_push
((2 3))
#46
Anything else we might add? / html parser
April 29, 2006, 02:34:21 PM
I wrote one a few days ago: http://en.feautec.pp.ru/store/libs/tags.lsp">http://en.feautec.pp.ru/store/libs/tags.lsp



It is able to parse structured tagged text like an html, is aware of unclosed tags and uses regexp for tags definition.



example:

for html:
<html><body>
test
<table align=center><tr><td>test1</td><tr><td>test2<td>test3</table>
</body></html>

here closed and unclosed tags are present



with syntax rules:
; tag format: (tag-sym tag-pattern tag-open|close|self (closes-tag closes-tag))
; tag-open - open a sublist and lead it
; tag-close - close a sublists and don't leave himself
; tag-self - close a sublists and leave himself
(set 'html-tags '(
      (table "<table(| [^>]*)>" tag-open ())
                  (table/ "</table>" tag-close (table th tr td))
                  (tr "<tr(| [^>]*)>" tag-open (tr th td))
                  (tr/ "</tr>" tag-close (tr th td))
                  (th "<th(| [^>]*)>" tag-open (th td))
                  (th/ "</th>" tag-close (th td))
                  (td "<td(| [^>]*)>" tag-open (th td))
                  (td/ "</td>" tag-close (th td))
                  (br "<br>" tag-self ())
                  (hr "<hr(| [^>]*)>" tag-self ())
                  (p "<p>" tag-self ())))


You can get following:
> (set 'htm (TAGS:parse-tags TAGS:html-tags (read-file "example.html")))

("<html><body>ntestn" TAGS:table TAGS:tr TAGS:td "test1" TAGS:td/ TAGS:tr
  TAGS:td "test2" TAGS:td "test3" TAGS:table/ "n</body></html>n")

Text is parsed and defined tags are replaced with symbols. One-dimension list.


> (TAGS:structure-tags TAGS:html-tags htm)

(TAGS:data "<html><body>ntestn"
  (TAGS:table (TAGS:tr (TAGS:td "test1"))
    (TAGS:tr (TAGS:td "test2") (TAGS:td "test3")))
  "n</body></html>n")

Preparsed list is converted to nested list according to defined tagging rules.

With such nested list, parsing of html-tables becames relatively useful...
#47
Checking the performace of different indexing techniques, I found strange result:
> (time
>   (dotimes (i 10000)
>     (dotimes (j 200)
>       (set 'b (nth j a)))))
1927
> (time
>   (dotimes (i 10000)
>     (dotimes (j 200)
>       (set 'b (j a)))))
55874

'a is a list of 200 one-space elements.



But documentation says:
QuoteImplicit indexing is slightly faster then indexing using nth and can take an unlimited number of indexes.

When 'a is a string of 200 spaces, then the difference is less dramatic - nth is only about 1.5 times faster.



Interesting, that slice and implicit slice timings has no such difference either for lists and strings.



newlisp ver. is 8.8.0-p2
#48
> (parse ""abc")
string token too long in function parse : "abcd1Pt08"

I have a suspection that when using internal parser, there is no range range checking for an input string.

Possible this could be dangerous...
#49
Anything else we might add? / (context?) and (sym)
April 15, 2006, 08:20:30 AM
> (sym "CON" MAIN nil)
CON
> (context? CON)
true
> (context? (sym "CON" MAIN nil))
nil

The conttext CON is already exists before this tests,



Is there a way to check the existence of a context given by a string?
#50
Anything else we might add? / (char) documentation
April 08, 2006, 02:38:51 PM
Quotesyntax: (char int)

Given an integer argument, char returns a string containing the ASCII character with value int.

Probably, it will be good to also mention that integers, greater than 255 are translated too, based on their lowest byte.

For noting the programmer that the range check may be needed.



Some systems (such as ncurses) uses integers, greater than 255 for various control keycodes.
#51
First, the bug:
dmi@dc:dmi$ newlisp
newLISP v.8.8.0-p2 on linux, execute 'newlisp -h' for more info.

> (global)
Segmentation fault


Second, a question:

How can I get a list of symbos of MAIN, that are maden global (either by

default or through (global sym))?
#52
Lutz, I just got an idea:


(+ 1.5 2.3) => 3

In my own practice, this implicit conversion from a float to an integer in functions, such as (+) and (-) mostly causes a mistakes and is really useful in rare cases.



Probably, it will be good - to supress the conversion (throw a type error) and force programmer convert it explicitly?
#53
Is there a way to know the version currently running?

For programmatically displaying a string like:

"newLISP v.8.8.0-p2 on linux"
#54
If I want to supply the context to eval-str, I must also specify an error-handler expression: (eval-str str expr ctx)

In this case, can error-handler to have access to the error-value, returned by evaluator?

Because in this syntax using (catch .... 'value) technique becames impossible.

Possible, can expr take one parameter, that is error-value?
#55
Anything else we might add? / (parse "" " ") ---- ()
February 02, 2006, 12:47:02 PM
>(parse "" " ")
()

When parsing an empty string the result will be an empty list.

My personal expectance was ("").

After thinking a bit, I'm agree that an empty list is an reasonal behavior.

But, possible, it would be good to reflect this in manual on (parse).
#56
Anything else we might add? / iconv/recode
January 26, 2006, 01:42:27 PM
Just wrote iconv wrapper. It seems to be working.

Potentially can convert to/from any encoding that libc's "iconv()" does.

Tested only on Linux... and I'm looking for comments about coding.

 
; iconv interface. See man 3 iconv. (C) Dmi
(context 'ICONV)

(set 'funcs '("iconv_open" "iconv" "iconv_close"))
(dolist (l funcs) (import "libc.so.6" l))

; iconv library function wrapper
; inbuf - string to recode
; with no-force does one iconv call,
;   returns list with iconv result, in-buffer/restsize, out-buffer/restsize.
; without no-force, if iconv call return error, drops broken symbol and
;   repeats iconv for the rest. Returns recodeed string.
(define (recode str no-force)
  (letn (strlen (length str)
         buflen (+ (* 2 strlen) 4)
         buf (dup "00" buflen)
         plen (pack "lu" buflen)
         pbuf (pack "ld" buf)
         rsize 0 bufrest 0)
     (do-until (or no-force (>= rsize 0) (<= strlen 0))
       (set 'pstrlen (pack "lu" strlen)
            'pstr (pack "ld" str))
       (set 'rsize (iconv cds pstr pstrlen pbuf plen))
       (set 'strlen ((unpack "lu" pstrlen) 0))
       (set 'str (get-string ((unpack "ld" pstr) 0)))
       (unless no-force
         (set 'str (1 strlen str)
              'strlen (- strlen 1))))
     (set 'buf (slice buf 0 (find "00" buf))
          'bufrest ((unpack "lu" plen) 0))
       (if no-force
         (list rsize str strlen buf bufrest)
         buf)))

; recode at once. do iconv_init, iconv and iconv_close together.
; also shows proposed usage for "recode"
(define (recode-once cfrom cto str no-force)
    (let (cds (iconv_open cto cfrom) res nil)
        (if (= -1 cds) -1
            (begin
                (set 'res (recode str no-force))
                (iconv_close cds)
                res))))

(context MAIN)

; example
;(println (ICONV:recode-once "KOI8R" "UTF-8" "abc провdefерка юникодаgh"))
#57
Anything else we might add? / unexpected logic
December 22, 2005, 09:08:27 AM
Recently I wrote the function ecase, which works like "case", but evaluates it's key-arguments before testing.
(define-macro (ecase _v)
  (eval (append (list 'case _v)
(map (fn (_i) (set-nth 0 _i (eval (_i 0))))
    (args)))))

But when I start using it, I got strange result:
> (setq a 1 b 2)
2
> (ecase 2 (a 7) (b 8) (true 9))
8
> (ecase 3 (a 7) (b 8) (true 9))
nil
> (eval '(case 3 (1 7) (2 8) (true 9)))
9

Debug investigations shows that my list transformations are correct, but the eval doesn't work:
newLISP v.8.7.1 on Win32 MinGW, execute 'newlisp -h' for more info.

> (setq a 1 b 2)
2
> (debug (ecase 3 (a 7) (b 8) (true 9)))

-----

(define-macro (ecase _v)
  #(let (_e (append (list 'case _v) (map (lambda (_i) (set-nth 0 _i
        (eval (_i 0))))
      (args))))
   (eval _e))#)

(global 'ecase)


[-> 3 ] s|tep n|ext c|ont q|uit > s

-----

(define-macro (ecase _v)
  (let (_e #(append (list 'case _v) (map (lambda (_i) (set-nth 0 _i
        (eval (_i 0))))
      (args)))#)
   (eval _e)))

(global 'ecase)


[-> 4 ] s|tep n|ext c|ont q|uit > n

-----

(define-macro (ecase _v)
  (let (_e #(append (list 'case _v) (map (lambda (_i) (set-nth 0 _i
        (eval (_i 0))))
      (args)))#)
   (eval _e)))

(global 'ecase)


RESULT: (case 3
 (1 7)
 (2 8)
 (true 9))

[<- 4 ] s|tep n|ext c|ont q|uit > s

-----

(define-macro (ecase _v)
  (let (_e (append (list 'case _v) (map (lambda (_i) (set-nth 0 _i
        (eval (_i 0))))
      (args))))
   #(eval _e)#))

(global 'ecase)


[-> 4 ] s|tep n|ext c|ont q|uit > _e
(case 3
 (1 7)
 (2 8)
 (true 9))
[-> 4 ] s|tep n|ext c|ont q|uit > (eval _e)
nil
[-> 4 ] s|tep n|ext c|ont q|uit > (save "e.lsp" '_e)
true
[-> 4 ] s|tep n|ext c|ont q|uit > s

-----

(define-macro (ecase _v)
  (let (_e (append (list 'case _v) (map (lambda (_i) (set-nth 0 _i
        (eval (_i 0))))
      (args))))
   #(eval _e)#))

(global 'ecase)


RESULT: nil

[<- 4 ] s|tep n|ext c|ont q|uit > c
nil
> (load "e.lsp")
(case 3
 (1 7)
 (2 8)
 (true 9))
> _e
(case 3
 (1 7)
 (2 8)
 (true 9))
> (eval _e)
9
>


Where am I wrong?
#58
Is there a way to destructive append to the end of string?

Similar to 'push?
#59
Anything else we might add? / using xml
December 16, 2005, 02:07:54 PM
Does anybody have a nice tricks for converting xml data into a traditional list structure?



xml-parse does the one-to-one conversion of symbolic xml structure to a list.

But I need to extract some particular data from xml into simple nested list structure, that can be easily processed with newlisp. And to skip all other unwanted tags and data.
#60
Suppose the file test.lsp is:
(set 's (parse (read-file (main-args 2))))
When I run



c:> newlisp test.lsp somefile.txt



newlisp executes test.lsp, then trying to execute somefile.txt and gots an error.



Is there a way to tell in test.lsp that interacrive mode should be invoked w/o interpreting next cmdline arguments?