Arc Forumnew | comments | leaders | submit | cthammett's commentslogin

Thank for the help, to summarise create .h and .c files:

  //StackArray.h

  #ifndef STACKARRAY_H
  #define STACKARRAY_H

  #define MAX 10

  typedef struct _stackarray{
	int array[MAX];
	int size;
  } StackArray;

  StackArray * newStackArray();
  int pushStackArray(StackArray *, int );
  int popStackArray(StackArray *);
  int fullStackArray(StackArray *);
  int emptyStackArray(StackArray *);
  void displayStackArray(StackArray *);
  void delete(StackArray *);
 
 #endif

  //StackArray.c

  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>
  #include "StackArray.h"

  StackArray * newStackArray(){
	StackArray * stack = malloc(sizeof(StackArray));
	int i;
	for(i = 0; i < MAX; i++){
		stack->array[i] = 0;
	}
	stack->size = 0;
	return stack;
  }

  int pushStackArray(StackArray * stack, int item){
	if(stack->size < MAX){
		stack->array[stack->size] =  item;
		stack->size++;
		return item;
	} else {
		printf("The stack is full\n");
		return 0;
	}
  }

  int popStackArray(StackArray * stack){
	if(stack->size > 0){
		int top = stack->array[stack->size-1];
		stack->size--;
		return top;
	} else {
		return 0;
	}
  }

  int fullStackArray(StackArray * stack){
	return stack->size == MAX ? 1 : 0;
 }
  int emptyStackArray(StackArray * stack){
	return stack->size == 0 ? 1 : 0;
  }

  void displayStackArray(StackArray * stack){
	if(stack->size > 0){
		int i;
		for(i = 0; i < stack->size; i++){
			printf("%d ", stack->array[i]);
		}
		printf("\n");
	} else if (stack->size == 0) {
		printf("The stack is empty\n");
	}
  }

  void delete(StackArray * stack){
	free(stack);
  }

  Compile and create the Shared Library (Linux):
  gcc -c -fPIC StackArray.c
  gcc -g -Wall -shared -o libStackArray.so StackArray.o

  In Anarki type in:
  
  ($:require ffi/unsafe
    ffi/unsafe/define
    ffi/unsafe/alloc)

  ;Define the library
  ($:define-ffi-definer define-StackArray (ffi-lib "/home/conan/Documents/Arcprojects/ffi/stack/libStackArray"))

  ;Define the functions input and ouput

  ($:define-StackArray newStackArray (_fun -> _pointer ))
  ($:define-StackArray delete (_fun _pointer -> _void ))
  ($:define-StackArray pushStackArray (_fun _pointer _int -> _void))
  ($:define-StackArray popStackArray  (_fun _pointer  -> _int))
  ($:define-StackArray fullStackArray  (_fun _pointer -> _int))
  ($:define-StackArray emptyStackArray  (_fun _pointer  -> _int))
  ($:define-StackArray displayStackArray  (_fun _pointer -> _void))

  ;assign the functions a symbol to use in Anarki
  (= newSA $.newStackArray)
  (= deleteSA $.delete)
  (= pushSA $.pushStackArray)
  (= popSA $.popStackArray)
  (= fullSA? $.fullStackArray)
  (= emptySA? $.emptyStackArray)
  (= displaySA $.displayStackArray)
  
  ;To use the functions
  (= stack (newSA))
  (emptySA? stack) 
  (pushSA stack 1)
  (displaySA stack)
  (fullSA? stack)
  (emptySA? stack)
  (popSA stack)
  (deleteSA stack)

 ;A lispy solution using closures with very little effort... a macro can be used to clean up the middle.
  (def Stack ()
    (with (items nil acc 0)
      (fn msg
        (let it (car (cdr msg))	
          (case (car msg)
             set
              (=  acc (len it) items it )
            empty?
              (is items nil)
            push 
              (do (= acc (inc acc)) (= items (join items (list it))) )
            pop 
              (if (> acc 0) (do (= acc (inc acc -1)) (= items (butlast items))))
            peek
              items
            size	
               acc)))))
 
  (= stack (Stack))
  (stack 'empty?)
  (stack 'push 1)
  (stack 'peek)
  (stack 'pop)
  (stack 'set '(1 2 3 4 5 6 7 8 9 10))

-----


Thanks mate, below are the error codes:

  (= stack (newSA))
  #<cpointer>

   (pushSA stack 1)
  stack: undefined;
   cannot reference undefined identifier
    context...:
     /home/conan/Documents/anarki-master/ac.scm:1225:4

  (fullSA? stack)
    stack: undefined;
   cannot reference undefined identifier
    context...:
   /home/conan/Documents/anarki-master/ac.scm:1225:4

  (empytSA? stack)
  _empytSA?: undefined;
   cannot reference undefined identifier
    context...:
   /home/conan/Documents/anarki-master/ac.scm:1225:4

  (displaySA stack)
  stack: undefined;
   cannot reference undefined identifier
    context...:
   /home/conan/Documents/anarki-master/ac.scm:1225:4

  stack
  #<cpointer>

  Here is the C code:

  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>
  #include "StackArray.h"

  void pushStackArray(StackArray * stack, int item){
	if(stack->size < MAX){
		stack->array[stack->size] =  item;
		stack->size++;
	} else {
		printf("The stack is full\n");
	}
  }

  int popStackArray(StackArray * stack){
	if(stack->size > 0){
		stack->size--;
	} else if(stack->size == 0){
		printf("Stack array is empty\n");
	}
	return stack->array[stack->size + 1];
  }

  int fullStackArray(StackArray * stack){
	return stack->size == MAX ? 1 : 0;
  }
  int emptyStackArray(StackArray * stack){
	return stack->size == 0 ? 1 : 0;
  }

  StackArray * newStackArray(){
	StackArray * stack = malloc(sizeof(StackArray));
	int i;
	for(i = 0; i < MAX; i++){
		stack->array[i] = 0;
	}
	stack->size = 0;
	return stack;
  }

  void displayStackArray(StackArray * stack){
	int i;
	for(i = 0; i < stack->size; i++){
		printf("%d ", stack->array[i]);
	}
	printf("\n");
  }

  void delete(StackArray * stack){
	free(stack); 
  }

-----

2 points by rocketnia 3195 days ago | link

Most of those errors are saying it can't find a global variable named "stack". That's because when you do (= stack (newSA)), you're creating a global variable called "stack" in Arc but it's called "_stack" in Racket. In your macros, you're generating Racket code that uses the Arc variable name, so it's looking for a "stack" Racket global that doesn't exist. You can potentially fix this in your macros... but why use macros when you already have functions that do what you want? :)

  (= newSA $.newStackArray)
  (= deleteSA $.delete)
  (= pushSA $.pushStackArray)
  (= popSA $.popStackArray)
  (= fullSA? $.fullStackArray)
  (= emptySA? $.emptyStackArray)
  (= displaySA $.displayStackArray)
If you absolutely need macros, then here's a fixed version of pushSA that embeds its arguments as Arc expressions rather than Racket expressions:

  (mac pushSA (stack x)
    `( ($:lambda (stack x)
         (pushStackArray stack x))
       ,stack ,x))
  ; or...
  (mac pushSA (stack x)
    `($.pushStackArray ,stack ,x))
Fixing the others would be similar, but I picked pushSA as an example because it has two arguments.

Finally, I think this line just has a simple typo:

  typo:  (emptytSA? stack)
  fix:   (emptySA? stack)
How far does this get you? I haven't tried your code, and I don't know if this will fix all your problems, but maybe it's a start!

-----

3 points by cthammett 3194 days ago | link

Hey thanks this works great. I just need to fix an easy bug in the C code for pop.

-----

2 points by cthammett 3241 days ago | link | parent | on: Parallelism and Data Oriented Design

Thanks for the tips, I'll keep on exploring the possibilities. On a side note, is there a c or python ffi for Anarki?

-----

2 points by akkartik 3241 days ago | link

In the past I just used the Racket FFI for C with anarki's $ operator.

Hold on, let me throw up this arc project of mine from many years ago. The FFI isn't on head, but here's how I imported a Porter stemming (https://en.wikipedia.org/wiki/Stemming) implementation and a keyword-guessing algorithm in C: https://github.com/akkartik/readwarp/blob/e281ecfefd/keyword.... C functions that that invokes: https://github.com/akkartik/readwarp/blob/e281ecfefd/keyword...

(There's a password for my mail delivery service in that repo, but that account is now defunct. Hopefully nothing else is confidential. Please be nice and let me know if you see something there that might damage me :)

-----

2 points by cthammett 3239 days ago | link

Thanks, I didn't see anything suspect. It should be a good learning experience calling c from Anarki. I saw a tutorial today how to create c callable functions using NASM x86-64 assembly code and it worked. Do you think assembly and Anarki can talk to each other through c?

-----

1 point by akkartik 3238 days ago | link

No reason they couldn't!

If you're into assembly I'd love to hear what you think of my current project to teach programming using a sort of idealized assembly: http://github.com/akkartik/mu. I'm co-designing the assembly language with the OS around it, in the spirit of C+unix.

-----

2 points by cthammett 3238 days ago | link

The project looks interesting. I would like to learn more about assembly to, have greater understanding and control over what my computer actually does. All the tests passed but I made mu crash using repl.mu, if this help in finding bugs?

  ./mu repl.mu
  ready! type in an instruction, then hit enter. ctrl-d exits.
  (+ 1 1)
  missing type in {name: "1", properties: ["1": ]}
  mu: 041name.cc:82 bool disqualified(reagent&): Assertion `!x.types.empty()' failed.
  Aborted (Core dumped)
Also my left, middle and right mouse button clicks were printing rubbish to the terminal after that. I restarted the terminal and mouse functionality was normal again.

-----

2 points by akkartik 3237 days ago | link

Thanks for trying it! It's not actually a Lisp :) Check out the examples in the readme.

The repl is sadly not done. Repl feels like the wrong metaphor. I'm writing on a more useful version in edit.mu, but that's far from done. For now sadly you have to type code into a file and run it as a separate step. Just for a couple more weeks, hopefully.

-----

2 points by cthammett 3237 days ago | link

Impressive project, how long have you been programming for? I'm not sure if I can be of much technical assistance but if you recommend a few tools I could probably learn more about testing and find bugs. Earlier this week I installed valgrind to check for errors and memory leaks and I'm looking for a debugger that will work with lubuntu. I am also learning assembly.

-----

1 point by akkartik 3237 days ago | link

I'm starting to feel old :) I've been programming for 16 years now.

Feel free to ask me more questions. I'm not looking for help, rather to help. But there's still some way to go. In the meantime I'll help in any other way. Valgrind is super useful for C programming.

-----

1 point by cthammett 3286 days ago | link | parent | on: Let Over lambda, Ch 6 Ichain intercept

Thank you for the tips and corrections.

-----

2 points by cthammett 3289 days ago | link | parent | on: On Lisp - Figure 18.5 matching function

Thanks this will be very useful.

-----

2 points by cthammett 3290 days ago | link | parent | on: On Lisp - Figure 18.5 matching function

What I have so far seems to work.

  ;is the element a var symbol? i.e ?x ?y.. etc.
  (mac varsym? (x)
    `(and (is (type ,x) 'sym) (is ((string ,x) 0) #\?)))

  ;Are both elements varsyms? i.e ?x = ?y (?x . ?y)
  (mac tvs? (x y)
    `(and (varsym? (car ,x))(varsym? (car ,y))))

  ;is element x a varsym that hasn't been added to binds?
  (mac xvs? (x y binds)
    `(and (varsym? (car ,x))(~varsym? (car ,y))(no (assoc (car ,x) ,binds))))

  ;is element y a varsym that hasn't been added to binds?
  (mac yvs? (x y binds)
    `(and (varsym? (car ,y)) (~varsym? (car ,x))(no (assoc (car ,y) ,binds))))

  ;make bind i. e  ((?x . a)(?y . b))
  (mac mb (a b binds)
    `(push (cons (car ,a) (car ,b)) ,binds))

  (def match (x y)
    (let binds nil
      ((afn (x y)
        (if (or (no x) (no y)) binds ;lists are missing
          (if (iso x y) binds        ;list are the same
            (do
              (if (tvs? x y) (mb x y binds))
              (if (xvs? x y binds) (mb x y binds))
              (if (yvs? x y binds) (mb y x binds))	
            (self cdr.x cdr.y)))))
      x y)))
Tests

  (match '(p ?x b ?y a) '(p ?y b c a))
    ((?y . c) (?x . ?y))

  (match '(p ?x b ?y ?z) '(p ?y b c a))
    ((?z . a) (?y . c) (?x . ?y))

  (match '(a b c) '(a a a))
    nil     ... i.e nil bindings since there are no vars

  (match '(a b c) '(a b c)) 
    nil

-----


  ;tree-leaves function for modifying leaves with plug-in test
  (def t-l%% (tree test result)
    (if tree
      (if (alist tree)
        (cons
          (t-l%% (car tree) test result)
          (t-l%% (cdr tree) test result))
        (if (test tree)
          (result tree)
        tree))))

  ;Modified akkartik's solution
  (mac t-l (tree test result)
    `(t-l%% ,tree 
      (fn (x) ,test) 
      (fn (x) ,result)))

  ;Using the following input
  (t-l `(1 2 (3 4 (5 6))) (and (number x) (even x)) 'even-number)

  ;Results
  (1 even-number (3 even-number (5 even-number)))

-----


Hey thank you this is very helpful for beginners like me. I am working through it to learn, practice and master the ideas presented in the book.

-----

1 point by akkartik 3298 days ago | link

You're welcome. By the way, if you add two spaces to a line on this forum it won't run through with the next one. Compare these two examples:

line1 line2

  line1
  line2
This is useful when showing code.

Feel free to ask more questions!

-----

2 points by cthammett 3293 days ago | link

Hey thanks for saving me further embarrassment. If I were to ask another question should I start another thread? In particular I am trying to translate to arc a matching function in Paul Graham's On Lisp, Fig 18.5. After this I am hoping to learn about Query Interpreters Fig 19.3 and Query Compilers Fig 19.6

-----

1 point by akkartik 3292 days ago | link

Whatever you like! Don't worry about dominating the frontpage or anything. Feel free to open new threads as needed.

-----