coroutines2.nut 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. local function _tokenizer(str) {
  2. local yield2 = suspend;
  3. local i = 0
  4. local i1,i2
  5. local find = function(pat) {
  6. local result = [0,0];
  7. //local rc = str.find_lua(pat,result,i)
  8. //print(str, pat, rc, result[0], result[1])
  9. if(str.find_lua(pat,result,i) >= 0) {
  10. i1 = result[0]
  11. i2 = result[1]
  12. return true;
  13. }
  14. return false;
  15. }
  16. local token = function() {
  17. //print(str, i, i1, i2)
  18. return str.slice(i,i2+1)
  19. }
  20. while (true) {
  21. if ( find("^%s+") ) {
  22. //-- ignore
  23. } else if( find( "^[%+%-]*%d+") ) {
  24. local ilast = i
  25. i = i2+1 //-- just after the sequence of digits
  26. //-- fractional part?
  27. local result = [0,0];
  28. if (str.find_lua("^%.%d+",result, i) >= 0) {
  29. i2 = result[1]
  30. i = i2+1
  31. }
  32. //-- exponent part?
  33. if (str.find_lua("^[eE][%+%-]*%d+", result, i) >= 0) {
  34. i2 = result[1]
  35. }
  36. i = ilast
  37. yield2(["number",str.slice(i,i2+1).tofloat()])
  38. } else if (find( "^[_%a][_%w]*")) {
  39. yield2(["iden",str.slice(i,i2+1)])
  40. } else if (find ([==[^"[^"]*"]==]) || find ("^'[^']*'") ) {
  41. //-- strip the quotes
  42. yield2(["string",str.slice(i+1,i2)])
  43. } else { //-- any other character
  44. if (i >= str.len()) return null;
  45. local ch = str[i].tochar()
  46. i2 = i
  47. yield2([ch,ch])
  48. }
  49. i = i2+1
  50. }
  51. }
  52. //for(var i=0; i < 10000; ++i) {
  53. local T = ::newthread(_tokenizer)
  54. var result = T.call([==[hello !-20.2e2 +10e1 "dolly"]==]);
  55. while( result ) {
  56. print(result[0], result[1]);
  57. result = T.wakeup()
  58. }
  59. //}